diff --git a/src/main/java/net/server/channel/handlers/MoveLifeHandler.java b/src/main/java/net/server/channel/handlers/MoveLifeHandler.java index 94b5871596..e29cc79277 100644 --- a/src/main/java/net/server/channel/handlers/MoveLifeHandler.java +++ b/src/main/java/net/server/channel/handlers/MoveLifeHandler.java @@ -27,10 +27,7 @@ import config.YamlConfig; import net.packet.InPacket; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import server.life.MobSkill; -import server.life.MobSkillFactory; -import server.life.Monster; -import server.life.MonsterInformationProvider; +import server.life.*; import server.maps.MapObject; import server.maps.MapObjectType; import server.maps.MapleMap; @@ -103,7 +100,7 @@ public final class MoveLifeHandler extends AbstractMovementPacketHandler { if (monster.canUseSkill(toUse, true)) { int animationTime = MonsterInformationProvider.getInstance().getMobSkillAnimationTime(toUse); - if (animationTime > 0 && toUse.getSkillId() != 129) { + if (animationTime > 0 && toUse.getType() != MobSkillType.BANISH) { toUse.applyDelayedEffect(player, monster, true, animationTime); } else { banishPlayers = new LinkedList<>(); diff --git a/src/main/java/server/life/MobSkill.java b/src/main/java/server/life/MobSkill.java index 5cb85cc8c5..35d9655f3b 100644 --- a/src/main/java/server/life/MobSkill.java +++ b/src/main/java/server/life/MobSkill.java @@ -47,7 +47,7 @@ import java.util.*; public class MobSkill { private static final Logger log = LoggerFactory.getLogger(MobSkill.class); - private final int skillId; + private final MobSkillType type; private final int skillLevel; private int mpCon; private final List toSummon = new ArrayList<>(); @@ -57,8 +57,8 @@ public class MobSkill { private Point lt, rb; private int limit; - public MobSkill(int skillId, int level) { - this.skillId = skillId; + public MobSkill(MobSkillType type, int level) { + this.type = type; this.skillLevel = level; } @@ -130,28 +130,12 @@ public class MobSkill { Disease disease = null; Map stats = new ArrayMap<>(); List reflection = new LinkedList<>(); - switch (skillId) { - case 100: - case 110: - case 150: - stats.put(MonsterStatus.WEAPON_ATTACK_UP, x); - break; - case 101: - case 111: - case 151: - stats.put(MonsterStatus.MAGIC_ATTACK_UP, x); - break; - case 102: - case 112: - case 152: - stats.put(MonsterStatus.WEAPON_DEFENSE_UP, x); - break; - case 103: - case 113: - case 153: - stats.put(MonsterStatus.MAGIC_DEFENSE_UP, x); - break; - case 114: + switch (type) { + case ATTACK_UP, ATTACK_UP_M, PAD -> stats.put(MonsterStatus.WEAPON_ATTACK_UP, x); + case MAGIC_ATTACK_UP, MAGIC_ATTACK_UP_M, MAD -> stats.put(MonsterStatus.MAGIC_ATTACK_UP, x); + case DEFENSE_UP, DEFENSE_UP_M, PDR -> stats.put(MonsterStatus.WEAPON_DEFENSE_UP, x); + case MAGIC_DEFENSE_UP, MAGIC_DEFENSE_UP_M, MDR -> stats.put(MonsterStatus.MAGIC_DEFENSE_UP, x); + case HEAL_M -> { if (lt != null && rb != null && skill) { List objects = getObjectsInRange(monster, MapObjectType.MONSTER); final int hps = (getX() / 1000) * (int) (950 + 1050 * Math.random()); @@ -161,29 +145,15 @@ public class MobSkill { } else { monster.heal(getX(), getY()); } - break; - case 120: - disease = Disease.SEAL; - break; - case 121: - disease = Disease.DARKNESS; - break; - case 122: - disease = Disease.WEAKEN; - break; - case 123: - disease = Disease.STUN; - break; - case 124: - disease = Disease.CURSE; - break; - case 125: - disease = Disease.POISON; - break; - case 126: // Slow - disease = Disease.SLOW; - break; - case 127: + } + case SEAL -> disease = Disease.SEAL; + case DARKNESS -> disease = Disease.DARKNESS; + case WEAKNESS -> disease = Disease.WEAKEN; + case STUN -> disease = Disease.STUN; + case CURSE -> disease = Disease.CURSE; + case POISON -> disease = Disease.POISON; + case SLOW -> disease = Disease.SLOW; + case DISPEL -> { if (lt != null && rb != null && skill) { for (Character character : getPlayersInRange(monster)) { character.dispel(); @@ -191,66 +161,52 @@ public class MobSkill { } else { player.dispel(); } - break; - case 128: // Seduce - disease = Disease.SEDUCE; - break; - case 129: // Banish + } + case SEDUCE -> disease = Disease.SEDUCE; + case BANISH -> { if (lt != null && rb != null && skill) { banishPlayers.addAll(getPlayersInRange(monster)); } else { banishPlayers.add(player); } - break; - case 131: // Mist + } + case AREA_POISON -> { monster.getMap().spawnMist(new Mist(calculateBoundingBox(monster.getPosition()), monster, this), x * 100, false, false, false); - break; - case 132: - disease = Disease.CONFUSE; - break; - case 133: // zombify - disease = Disease.ZOMBIFY; - break; - case 140: + } + case REVERSE_INPUT -> disease = Disease.CONFUSE; + case UNDEAD -> disease = Disease.ZOMBIFY; + case PHYSICAL_IMMUNE -> { if (makeChanceResult() && !monster.isBuffed(MonsterStatus.MAGIC_IMMUNITY)) { stats.put(MonsterStatus.WEAPON_IMMUNITY, x); } - break; - case 141: + } + case MAGIC_IMMUNE -> { if (makeChanceResult() && !monster.isBuffed(MonsterStatus.WEAPON_IMMUNITY)) { stats.put(MonsterStatus.MAGIC_IMMUNITY, x); } - break; - case 143: // Weapon Reflect + } + case PHYSICAL_COUNTER -> { stats.put(MonsterStatus.WEAPON_REFLECT, 10); stats.put(MonsterStatus.WEAPON_IMMUNITY, 10); reflection.add(x); - break; - case 144: // Magic Reflect + } + case MAGIC_COUNTER -> { stats.put(MonsterStatus.MAGIC_REFLECT, 10); stats.put(MonsterStatus.MAGIC_IMMUNITY, 10); reflection.add(x); - break; - case 145: // Weapon / Magic reflect + } + case PHYSICAL_AND_MAGIC_COUNTER -> { stats.put(MonsterStatus.WEAPON_REFLECT, 10); stats.put(MonsterStatus.WEAPON_IMMUNITY, 10); stats.put(MonsterStatus.MAGIC_REFLECT, 10); stats.put(MonsterStatus.MAGIC_IMMUNITY, 10); reflection.add(x); - break; - case 154: - stats.put(MonsterStatus.ACC, x); - break; - case 155: - stats.put(MonsterStatus.AVOID, x); - break; - case 156: - stats.put(MonsterStatus.SPEED, x); - break; - case 157: - stats.put(MonsterStatus.SEAL_SKILL, x); - break; - case 200: // summon + } + case ACC -> stats.put(MonsterStatus.ACC, x); + case EVA -> stats.put(MonsterStatus.AVOID, x); + case SPEED -> stats.put(MonsterStatus.SPEED, x); + case SEAL_SKILL -> stats.put(MonsterStatus.SEAL_SKILL, x); + case SUMMON -> { int skillLimit = this.getLimit(); MapleMap map = monster.getMap(); @@ -322,18 +278,15 @@ public class MobSkill { } } } - break; - default: - log.warn("Unhandled Mob skill: {}", skillId); - break; + } } if (stats.size() > 0) { if (lt != null && rb != null && skill) { for (MapObject mons : getObjectsInRange(monster, MapObjectType.MONSTER)) { - ((Monster) mons).applyMonsterBuff(stats, getX(), getSkillId(), getDuration(), this, reflection); + ((Monster) mons).applyMonsterBuff(stats, getX(), type.getId(), getDuration(), this, reflection); } } else { - monster.applyMonsterBuff(stats, getX(), getSkillId(), getDuration(), this, reflection); + monster.applyMonsterBuff(stats, getX(), type.getId(), getDuration(), this, reflection); } } if (disease != null) { @@ -361,8 +314,12 @@ public class MobSkill { return monster.getMap().getPlayersInRange(calculateBoundingBox(monster.getPosition())); } + public MobSkillType getType() { + return type; + } + public int getSkillId() { - return skillId; + return type.getId(); } public int getSkillLevel() { diff --git a/src/main/java/server/life/MobSkillFactory.java b/src/main/java/server/life/MobSkillFactory.java index 055cbbc695..0e9cee415b 100644 --- a/src/main/java/server/life/MobSkillFactory.java +++ b/src/main/java/server/life/MobSkillFactory.java @@ -63,8 +63,7 @@ public class MobSkillFactory { } writeLock.lock(); try { - MobSkill ret; - ret = mobSkills.get(key); + MobSkill ret = mobSkills.get(key); if (ret == null) { Data skillData = skillRoot.getChildByPath(skillId + "/level/" + level); if (skillData != null) { @@ -93,7 +92,7 @@ public class MobSkillFactory { lt = (Point) ltd.getData(); rb = (Point) skillData.getChildByPath("rb").getData(); } - ret = new MobSkill(skillId, level); + ret = new MobSkill(MobSkillType.from(skillId), level); ret.addSummons(toSummon); ret.setCoolTime(cooltime); ret.setDuration(duration); diff --git a/src/main/java/server/life/MobSkillType.java b/src/main/java/server/life/MobSkillType.java new file mode 100644 index 0000000000..c16b8ba3cb --- /dev/null +++ b/src/main/java/server/life/MobSkillType.java @@ -0,0 +1,61 @@ +package server.life; + +import java.util.Arrays; + +public enum MobSkillType { + ATTACK_UP(100), + MAGIC_ATTACK_UP(101), + DEFENSE_UP(102), + MAGIC_DEFENSE_UP(103), + ATTACK_UP_M(110), + MAGIC_ATTACK_UP_M(111), + DEFENSE_UP_M(112), + MAGIC_DEFENSE_UP_M(113), + HEAL_M(114), + HASTE_M(115), + SEAL(120), + DARKNESS(121), + WEAKNESS(122), + STUN(123), + CURSE(124), + POISON(125), + SLOW(126), + DISPEL(127), + SEDUCE(128), + BANISH(129), + AREA_POISON(131), + REVERSE_INPUT(132), + UNDEAD(133), + STOP_POTION(134), + STOP_MOTION(135), + FEAR(136), + PHYSICAL_IMMUNE(140), + MAGIC_IMMUNE(141), + HARD_SKIN(142), + PHYSICAL_COUNTER(143), + MAGIC_COUNTER(144), + PHYSICAL_AND_MAGIC_COUNTER(145), + PAD(150), + MAD(151), + PDR(152), + MDR(153), + ACC(154), + EVA(155), + SPEED(156), + SEAL_SKILL(157), + SUMMON(200); + + private final int id; + + MobSkillType(int id) { + this.id = id; + } + + public static MobSkillType from(int id) { + return Arrays.stream(values()).findFirst().orElseThrow(IllegalArgumentException::new); + } + + public int getId() { + return id; + } +} diff --git a/src/main/java/server/life/Monster.java b/src/main/java/server/life/Monster.java index a494c01915..77c1bb9dd9 100644 --- a/src/main/java/server/life/Monster.java +++ b/src/main/java/server/life/Monster.java @@ -1276,11 +1276,11 @@ public class Monster extends AbstractLoadedLife { return true; } - public final void dispelSkill(final MobSkill skillId) { + public final void dispelSkill(final MobSkill skill) { List toCancel = new ArrayList<>(); for (Entry effects : stati.entrySet()) { MonsterStatusEffect mse = effects.getValue(); - if (mse.getMobSkill() != null && mse.getMobSkill().getSkillId() == skillId.getSkillId()) { //not checking for level. + if (mse.getMobSkill() != null && mse.getMobSkill().getType() == skill.getType()) { //not checking for level. toCancel.add(effects.getKey()); } } @@ -1452,8 +1452,7 @@ public class Monster extends AbstractLoadedLife { return false; } - int useSkillid = toUse.getSkillId(); - if (useSkillid >= 143 && useSkillid <= 145) { + if (isReflectSkill(toUse)) { if (this.isBuffed(MonsterStatus.WEAPON_REFLECT) || this.isBuffed(MonsterStatus.MAGIC_REFLECT)) { return false; } @@ -1462,7 +1461,7 @@ public class Monster extends AbstractLoadedLife { monsterLock.lock(); try { for (Pair skill : usedSkills) { // thanks OishiiKawaiiDesu for noticing an issue with mobskill cooldown - if (skill.getLeft() == useSkillid && skill.getRight() == toUse.getSkillLevel()) { + if (skill.getLeft() == toUse.getSkillId() && skill.getRight() == toUse.getSkillLevel()) { return false; } } @@ -1488,8 +1487,16 @@ public class Monster extends AbstractLoadedLife { return true; } + private boolean isReflectSkill(MobSkill mobSkill) { + return switch (mobSkill.getType()) { + case PHYSICAL_COUNTER, MAGIC_COUNTER, PHYSICAL_AND_MAGIC_COUNTER -> true; + default -> false ; + }; + } + private void usedSkill(MobSkill skill) { - final int skillId = skill.getSkillId(), level = skill.getSkillLevel(); + final int skillId = skill.getSkillId(); + final int level = skill.getSkillLevel(); long cooltime = skill.getCoolTime(); monsterLock.lock();