diff --git a/pom.xml b/pom.xml index b9e1ae39..842ec39a 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 net.Indyuce MMOCore - 1.8.3 + 1.9 MMOCore Offer your players a brand new RPG experience!! @@ -125,7 +125,7 @@ io.lumine MythicLib-dist - 1.2 + 1.3-R11 provided @@ -177,12 +177,5 @@ provided - - me.vagdedes.spartan - SpartanAPI - 1.0 - provided - - diff --git a/src/main/java/net/Indyuce/mmocore/MMOCore.java b/src/main/java/net/Indyuce/mmocore/MMOCore.java index feffb6d5..fbf7c55f 100644 --- a/src/main/java/net/Indyuce/mmocore/MMOCore.java +++ b/src/main/java/net/Indyuce/mmocore/MMOCore.java @@ -13,8 +13,6 @@ import net.Indyuce.mmocore.api.player.stats.StatType; import net.Indyuce.mmocore.api.util.debug.DebugMode; import net.Indyuce.mmocore.command.*; import net.Indyuce.mmocore.comp.MMOCoreTargetRestriction; -import net.Indyuce.mmocore.comp.anticheat.AntiCheatSupport; -import net.Indyuce.mmocore.comp.anticheat.SpartanPlugin; import net.Indyuce.mmocore.comp.citizens.CitizenInteractEventListener; import net.Indyuce.mmocore.comp.citizens.CitizensMMOLoader; import net.Indyuce.mmocore.comp.mythicmobs.MythicHook; @@ -41,6 +39,9 @@ import net.Indyuce.mmocore.manager.profession.*; import net.Indyuce.mmocore.manager.social.BoosterManager; import net.Indyuce.mmocore.manager.social.PartyManager; import net.Indyuce.mmocore.manager.social.RequestManager; +import net.Indyuce.mmocore.skill.list.Ambers; +import net.Indyuce.mmocore.skill.list.Neptune_Gift; +import net.Indyuce.mmocore.skill.list.Sneaky_Picky; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.command.CommandMap; @@ -57,15 +58,9 @@ public class MMOCore extends LuminePlugin { public ConfigManager configManager; public WaypointManager waypointManager; - public RestrictionManager restrictionManager; public SoundManager soundManager; public RequestManager requestManager; public ConfigItemManager configItems; - public VaultEconomy economy; - public AntiCheatSupport antiCheatSupport; - public RegionHandler regionHandler = new DefaultRegionHandler(); - public PlaceholderParser placeholderParser = new DefaultParser(); - public DataProvider dataProvider = new YAMLDataProvider(); public final PlayerActionBar actionBarManager = new PlayerActionBar(); public final SkillManager skillManager = new SkillManager(); public final ClassManager classManager = new ClassManager(); @@ -77,6 +72,13 @@ public class MMOCore extends LuminePlugin { public final ProfessionManager professionManager = new ProfessionManager(); public final net.Indyuce.mmocore.manager.ExperienceManager experience = new net.Indyuce.mmocore.manager.ExperienceManager(); public final LootChestManager lootChests = new LootChestManager(); + public final MMOLoadManager loadManager = new MMOLoadManager(); + public final RestrictionManager restrictionManager = new RestrictionManager(); + + public VaultEconomy economy; + public RegionHandler regionHandler = new DefaultRegionHandler(); + public PlaceholderParser placeholderParser = new DefaultParser(); + public DataProvider dataProvider = new YAMLDataProvider(); // Profession managers public final net.Indyuce.mmocore.manager.profession.CustomBlockManager mineManager = new net.Indyuce.mmocore.manager.profession.CustomBlockManager(); @@ -85,8 +87,6 @@ public class MMOCore extends LuminePlugin { public final EnchantManager enchantManager = new EnchantManager(); public final SmithingManager smithingManager = new SmithingManager(); - public final MMOLoadManager loadManager = new MMOLoadManager(); - public boolean shouldDebugSQL = false; private static final int MYTHICLIB_COMPATIBILITY_INDEX = 1; @@ -118,6 +118,11 @@ public class MMOCore extends LuminePlugin { if (Bukkit.getPluginManager().getPlugin("MythicMobs") != null) loadManager.registerLoader(new MythicMobsMMOLoader()); + + // Register MMOCore specific skills + MythicLib.plugin.getSkills().registerSkillHandler(new Ambers()); + MythicLib.plugin.getSkills().registerSkillHandler(new Neptune_Gift()); + MythicLib.plugin.getSkills().registerSkillHandler(new Sneaky_Picky()); } public void enable() { @@ -156,11 +161,6 @@ public class MMOCore extends LuminePlugin { getLogger().log(Level.INFO, "Hooked onto WorldGuard"); } - if (Bukkit.getPluginManager().getPlugin("Spartan") != null) { - antiCheatSupport = new SpartanPlugin(); - getLogger().log(Level.INFO, "Hooked onto Spartan"); - } - if (Bukkit.getPluginManager().getPlugin("MythicMobs") != null) { Bukkit.getServer().getPluginManager().registerEvents(new MythicHook(), this); MMOCore.plugin.getLogger().log(Level.INFO, "Hooked onto MythicMobs"); @@ -368,9 +368,9 @@ public class MMOCore extends LuminePlugin { questManager.initialize(clearBefore); lootChests.initialize(clearBefore); + restrictionManager.initialize(clearBefore); waypointManager = new WaypointManager(new ConfigFile("waypoints").getConfig()); - restrictionManager = new RestrictionManager(new ConfigFile("restrictions").getConfig()); requestManager = new RequestManager(); soundManager = new SoundManager(new ConfigFile("sounds").getConfig()); configItems = new ConfigItemManager(new ConfigFile("items").getConfig()); @@ -401,10 +401,6 @@ public class MMOCore extends LuminePlugin { return getFile(); } - public boolean hasAntiCheat() { - return antiCheatSupport != null; - } - public boolean hasEconomy() { return economy != null && economy.isValid(); } diff --git a/src/main/java/net/Indyuce/mmocore/api/ConfigFile.java b/src/main/java/net/Indyuce/mmocore/api/ConfigFile.java index 36ebbfdb..178191d6 100644 --- a/src/main/java/net/Indyuce/mmocore/api/ConfigFile.java +++ b/src/main/java/net/Indyuce/mmocore/api/ConfigFile.java @@ -42,6 +42,10 @@ public class ConfigFile { config = YamlConfiguration.loadConfiguration(file = new File(plugin.getDataFolder() + folder, (this.name = name) + ".yml")); } + public boolean exists() { + return file.exists(); + } + public FileConfiguration getConfig() { return config; } diff --git a/src/main/java/net/Indyuce/mmocore/api/event/PlayerPostCastSkillEvent.java b/src/main/java/net/Indyuce/mmocore/api/event/PlayerPostCastSkillEvent.java deleted file mode 100644 index 8f3147bd..00000000 --- a/src/main/java/net/Indyuce/mmocore/api/event/PlayerPostCastSkillEvent.java +++ /dev/null @@ -1,48 +0,0 @@ -package net.Indyuce.mmocore.api.event; - -import net.Indyuce.mmocore.api.player.PlayerData; -import net.Indyuce.mmocore.skill.Skill.SkillInfo; -import net.Indyuce.mmocore.skill.metadata.SkillMetadata; -import org.bukkit.event.HandlerList; - -public class PlayerPostCastSkillEvent extends PlayerDataEvent { - private static final HandlerList handlers = new HandlerList(); - - private final SkillInfo skill; - private final SkillMetadata result; - - /** - * Called right after a player casts a skill. - * - * @param playerData Player casting the skill - * @param skill Skill being cast - * @param result SKill casting result - */ - public PlayerPostCastSkillEvent(PlayerData playerData, SkillInfo skill, SkillMetadata result) { - super(playerData); - - this.skill = skill; - this.result = result; - } - - public SkillInfo getCast() { - return skill; - } - - public SkillMetadata getResult() { - return result; - } - - public boolean wasSuccessful() { - return result.isSuccessful(); - } - - @Override - public HandlerList getHandlers() { - return handlers; - } - - public static HandlerList getHandlerList() { - return handlers; - } -} diff --git a/src/main/java/net/Indyuce/mmocore/api/event/PlayerPreCastSkillEvent.java b/src/main/java/net/Indyuce/mmocore/api/event/PlayerPreCastSkillEvent.java deleted file mode 100644 index 4bbc45db..00000000 --- a/src/main/java/net/Indyuce/mmocore/api/event/PlayerPreCastSkillEvent.java +++ /dev/null @@ -1,50 +0,0 @@ -package net.Indyuce.mmocore.api.event; - -import net.Indyuce.mmocore.api.player.PlayerData; -import net.Indyuce.mmocore.skill.Skill.SkillInfo; -import org.bukkit.event.Cancellable; -import org.bukkit.event.HandlerList; - -public class PlayerPreCastSkillEvent extends PlayerDataEvent implements Cancellable { - private static final HandlerList handlers = new HandlerList(); - - private final SkillInfo skill; - - private boolean cancelled; - - /** - * Called right before a player casts a skill. This occurs before - * checking for mana, stamina costs and ability cooldown. - * - * @param playerData Player casting the skill - * @param skill Skill being cast - */ - public PlayerPreCastSkillEvent(PlayerData playerData, SkillInfo skill) { - super(playerData); - - this.skill = skill; - } - - public SkillInfo getCast() { - return skill; - } - - @Override - public boolean isCancelled() { - return cancelled; - } - - @Override - public void setCancelled(boolean value) { - cancelled = value; - } - - @Override - public HandlerList getHandlers() { - return handlers; - } - - public static HandlerList getHandlerList() { - return handlers; - } -} diff --git a/src/main/java/net/Indyuce/mmocore/api/player/PlayerData.java b/src/main/java/net/Indyuce/mmocore/api/player/PlayerData.java index dbf199b3..0582d2d3 100644 --- a/src/main/java/net/Indyuce/mmocore/api/player/PlayerData.java +++ b/src/main/java/net/Indyuce/mmocore/api/player/PlayerData.java @@ -2,7 +2,6 @@ package net.Indyuce.mmocore.api.player; import io.lumine.mythic.lib.api.player.MMOPlayerData; import io.lumine.mythic.lib.player.TemporaryPlayerData; -import io.lumine.mythic.lib.player.cooldown.CooldownInfo; import io.lumine.mythic.lib.player.cooldown.CooldownMap; import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.api.ConfigMessage; @@ -27,11 +26,8 @@ import net.Indyuce.mmocore.experience.EXPSource; import net.Indyuce.mmocore.experience.PlayerProfessions; import net.Indyuce.mmocore.listener.SpellCast.SkillCasting; import net.Indyuce.mmocore.manager.SoundManager; -import net.Indyuce.mmocore.skill.CasterMetadata; -import net.Indyuce.mmocore.skill.Skill; -import net.Indyuce.mmocore.skill.Skill.SkillInfo; -import net.Indyuce.mmocore.skill.metadata.SkillMetadata; -import net.Indyuce.mmocore.skill.metadata.SkillMetadata.CancelReason; +import net.Indyuce.mmocore.skill.ClassSkill; +import net.Indyuce.mmocore.skill.RegisteredSkill; import net.md_5.bungee.api.ChatMessageType; import net.md_5.bungee.api.chat.TextComponent; import org.bukkit.*; @@ -72,7 +68,7 @@ public class PlayerData extends OfflinePlayerData implements Closable { private final List friends = new ArrayList<>(); private final Set waypoints = new HashSet<>(); private final Map skills = new HashMap<>(); - private final List boundSkills = new ArrayList<>(); + private final List boundSkills = new ArrayList<>(); private final PlayerProfessions collectSkills = new PlayerProfessions(this); private final PlayerAttributes attributes = new PlayerAttributes(this); private final Map classSlots = new HashMap<>(); @@ -139,7 +135,7 @@ public class PlayerData extends OfflinePlayerData implements Closable { } catch (NullPointerException npe1) { boundSkills.remove(j); try { - MMOCore.log(Level.SEVERE, "[Userdata] Could not find skill " + boundSkills.get(j).getSkill().getId() + " in class " + MMOCore.log(Level.SEVERE, "[Userdata] Could not find skill " + boundSkills.get(j).getSkill().getHandler().getId() + " in class " + getProfess().getId() + " while refreshing player data."); } catch (NullPointerException npe2) { MMOCore.log(Level.SEVERE, @@ -719,12 +715,12 @@ public class PlayerData extends OfflinePlayerData implements Closable { return getAttributes().mapPoints(); } - public int getSkillLevel(Skill skill) { - return skills.getOrDefault(skill.getId(), 1); + public int getSkillLevel(RegisteredSkill skill) { + return skills.getOrDefault(skill.getHandler().getId(), 1); } - public void setSkillLevel(Skill skill, int level) { - setSkillLevel(skill.getId(), level); + public void setSkillLevel(RegisteredSkill skill, int level) { + setSkillLevel(skill.getHandler().getId(), level); } public void setSkillLevel(String skill, int level) { @@ -735,12 +731,12 @@ public class PlayerData extends OfflinePlayerData implements Closable { skills.remove(skill); } - /* - * better use getProfess().findSkill(skill).isPresent() + /** + * @deprecated use {@link PlayerClass#findSkill(RegisteredSkill)} instead */ @Deprecated - public boolean hasSkillUnlocked(Skill skill) { - return getProfess().hasSkill(skill.getId()) && hasSkillUnlocked(getProfess().getSkill(skill.getId())); + public boolean hasSkillUnlocked(RegisteredSkill skill) { + return getProfess().hasSkill(skill.getHandler().getId()) && hasSkillUnlocked(getProfess().getSkill(skill.getHandler().getId())); } /** @@ -753,8 +749,8 @@ public class PlayerData extends OfflinePlayerData implements Closable { * * @return If the player unlocked the skill */ - public boolean hasSkillUnlocked(SkillInfo info) { - return getLevel() >= info.getUnlockLevel(); + public boolean hasSkillUnlocked(ClassSkill skill) { + return getLevel() >= skill.getUnlockLevel(); } public Map mapSkillLevels() { @@ -789,7 +785,7 @@ public class PlayerData extends OfflinePlayerData implements Closable { this.profess = profess; // Clear old skills - for (Iterator iterator = boundSkills.iterator(); iterator.hasNext(); ) + for (Iterator iterator = boundSkills.iterator(); iterator.hasNext(); ) if (!getProfess().hasSkill(iterator.next().getSkill())) iterator.remove(); @@ -801,11 +797,11 @@ public class PlayerData extends OfflinePlayerData implements Closable { return slot < boundSkills.size(); } - public SkillInfo getBoundSkill(int slot) { + public ClassSkill getBoundSkill(int slot) { return slot >= boundSkills.size() ? null : boundSkills.get(slot); } - public void setBoundSkill(int slot, SkillInfo skill) { + public void setBoundSkill(int slot, ClassSkill skill) { if (boundSkills.size() < 6) boundSkills.add(skill); else @@ -816,7 +812,7 @@ public class PlayerData extends OfflinePlayerData implements Closable { boundSkills.remove(slot); } - public List getBoundSkills() { + public List getBoundSkills() { return boundSkills; } @@ -849,59 +845,6 @@ public class PlayerData extends OfflinePlayerData implements Closable { combat = new CombatRunnable(this); } - public SkillMetadata cast(Skill skill) { - return cast(getProfess().getSkill(skill)); - } - - public SkillMetadata cast(SkillInfo skill) { - - PlayerPreCastSkillEvent preEvent = new PlayerPreCastSkillEvent(this, skill); - Bukkit.getPluginManager().callEvent(preEvent); - if (preEvent.isCancelled()) - return new SkillMetadata(this, skill, CancelReason.OTHER); - - // Check for mana/stamina/cooldown and cast skill - CasterMetadata casterMeta = new CasterMetadata(this); - SkillMetadata cast = skill.getSkill().whenCast(casterMeta, skill); - - // Send failure messages - if (!cast.isSuccessful()) { - if (!skill.getSkill().isPassive() && isOnline()) { - if (cast.getCancelReason() == CancelReason.LOCKED) - MMOCore.plugin.configManager.getSimpleMessage("not-unlocked-skill").send(getPlayer()); - - if (cast.getCancelReason() == CancelReason.MANA) - MMOCore.plugin.configManager.getSimpleMessage("casting.no-mana", "mana", getProfess().getManaDisplay().getName()).send(getPlayer()); - - if (cast.getCancelReason() == CancelReason.STAMINA) - MMOCore.plugin.configManager.getSimpleMessage("casting.no-stamina").send(getPlayer()); - - if (cast.getCancelReason() == CancelReason.COOLDOWN) - MMOCore.plugin.configManager.getSimpleMessage("casting.on-cooldown").send(getPlayer()); - } - - PlayerPostCastSkillEvent postEvent = new PlayerPostCastSkillEvent(this, skill, cast); - Bukkit.getPluginManager().callEvent(postEvent); - return cast; - } - - // Apply cooldown, mana and stamina costs - if (!noCooldown) { - - // Cooldown - double flatCooldownReduction = Math.max(0, Math.min(1, getStats().getStat(StatType.COOLDOWN_REDUCTION) / 100)); - CooldownInfo cooldownHandler = getCooldownMap().applyCooldown(cast.getSkill(), cast.getCooldown()); - cooldownHandler.reduceInitialCooldown(flatCooldownReduction); - - giveMana(-cast.getManaCost(), PlayerResourceUpdateEvent.UpdateReason.SKILL_COST); - giveStamina(-cast.getStaminaCost(), PlayerResourceUpdateEvent.UpdateReason.SKILL_COST); - } - - PlayerPostCastSkillEvent postEvent = new PlayerPostCastSkillEvent(this, skill, cast); - Bukkit.getPluginManager().callEvent(postEvent); - return cast; - } - @Override public int hashCode() { return mmoData.hashCode(); diff --git a/src/main/java/net/Indyuce/mmocore/api/player/stats/PlayerStats.java b/src/main/java/net/Indyuce/mmocore/api/player/stats/PlayerStats.java index 614592ba..594f1a9e 100644 --- a/src/main/java/net/Indyuce/mmocore/api/player/stats/PlayerStats.java +++ b/src/main/java/net/Indyuce/mmocore/api/player/stats/PlayerStats.java @@ -7,8 +7,7 @@ import io.lumine.mythic.lib.api.stat.modifier.ModifierSource; import io.lumine.mythic.lib.api.stat.modifier.ModifierType; import io.lumine.mythic.lib.api.stat.modifier.StatModifier; import net.Indyuce.mmocore.api.player.PlayerData; -import net.Indyuce.mmocore.comp.mythicmobs.MythicSkill; -import net.Indyuce.mmocore.skill.Skill; +import net.Indyuce.mmocore.skill.ClassSkill; public class PlayerStats { private final PlayerData data; @@ -82,8 +81,8 @@ public class PlayerStats { * This updates the player's passive skills */ data.getMMOPlayerData().unregisterSkillTriggers("MMOCorePassiveSkill"); - for (Skill.SkillInfo skill : data.getProfess().getSkills()) - if (skill.getSkill().isPassive() && skill.getSkill() instanceof MythicSkill) - data.getMMOPlayerData().registerSkillTrigger(((MythicSkill) skill.getSkill()).toMythicLib()); + for (ClassSkill skill : data.getProfess().getSkills()) + if (skill.getSkill().hasTrigger()) + data.getMMOPlayerData().registerSkillTrigger(skill.toPassive(data)); } } diff --git a/src/main/java/net/Indyuce/mmocore/api/util/MMOCoreUtils.java b/src/main/java/net/Indyuce/mmocore/api/util/MMOCoreUtils.java index 33701be5..1a5f73f1 100644 --- a/src/main/java/net/Indyuce/mmocore/api/util/MMOCoreUtils.java +++ b/src/main/java/net/Indyuce/mmocore/api/util/MMOCoreUtils.java @@ -2,12 +2,10 @@ package net.Indyuce.mmocore.api.util; import io.lumine.mythic.lib.MythicLib; import io.lumine.mythic.lib.api.item.NBTItem; -import io.lumine.mythic.lib.comp.target.InteractionType; import io.lumine.mythic.lib.version.VersionMaterial; import io.lumine.mythic.utils.holograms.Hologram; import io.lumine.mythic.utils.serialize.Position; import net.Indyuce.mmocore.MMOCore; -import net.Indyuce.mmocore.api.player.PlayerData; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Material; @@ -173,26 +171,6 @@ public class MMOCoreUtils { return entities; } - /** - * @param player Player casting a spell/basic attack - * @param target The target entity - * @return If the player can attack the entity - */ - public static boolean canTarget(PlayerData player, Entity target) { - return canTarget(player, target, InteractionType.OFFENSE_SKILL); - } - - /** - * @param player Player casting a spell/basic attack - * @param target The target entity - * @param interaction Whether the action is an attack or a buff, this does - * impact the outcome of the friendly fire check - * @return If the player can target the entity given the attack type (buff or attack) - */ - public static boolean canTarget(PlayerData player, Entity target, InteractionType interaction) { - return target instanceof LivingEntity && MythicLib.plugin.getEntities().canTarget(player.getPlayer(), target, interaction); - } - public static void heal(LivingEntity target, double value) { double max = target.getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue(); double gain = Math.min(max, target.getHealth() + value) - target.getHealth(); diff --git a/src/main/java/net/Indyuce/mmocore/comp/anticheat/AntiCheatSupport.java b/src/main/java/net/Indyuce/mmocore/comp/anticheat/AntiCheatSupport.java deleted file mode 100644 index 55390dea..00000000 --- a/src/main/java/net/Indyuce/mmocore/comp/anticheat/AntiCheatSupport.java +++ /dev/null @@ -1,9 +0,0 @@ -package net.Indyuce.mmocore.comp.anticheat; - -import java.util.Map; - -import org.bukkit.entity.Player; - -public abstract class AntiCheatSupport { - public abstract void disableAntiCheat(Player player, Map map); -} diff --git a/src/main/java/net/Indyuce/mmocore/comp/anticheat/CheatType.java b/src/main/java/net/Indyuce/mmocore/comp/anticheat/CheatType.java deleted file mode 100644 index 1cab85ab..00000000 --- a/src/main/java/net/Indyuce/mmocore/comp/anticheat/CheatType.java +++ /dev/null @@ -1,44 +0,0 @@ -package net.Indyuce.mmocore.comp.anticheat; - -public enum CheatType { - GENERAL_EXPLOITS("Exploits"), - NO_SWING("NoSwing"), - MOVEMENT("IrregularMovements"), - CLIPPING("Clip"), - IMPOSSIBLE_ACTION("ImpossibleActions"), - INVENTORY_CLEAR("ItemDrops"), - INVENTORY_CLICKS("InventoryClicks"), - AUTO_SPRINT("Sprint"), - JESUS("Jesus"), - NO_SLOWDOWN("NoSlowdown"), - CRITICAL_HITS("Criticals"), - NUKER("Nuker"), - GHOST_HAND("GhostHand"), - LIQUIDS("Liquids"), - BLOCK_REACH("BlockReach"), - ELYTRA("ElytraMove"), - BOAT("BoatMove"), - FAST_BOW("FastBow"), - FAST_CLICK("FastClicks"), - FAST_HEAL("FastHeal"), - FLYING("Fly"), - HIT_REACH("HitReach"), - FAST_BREAK("FastBreak"), - FAST_PLACE("FastPlace"), - SPEED("Speed"), - NO_FALL("NoFall"), - ILLEGAL_POS("IllegalPosition"), - FAST_EAT("FastEat"), - VELOCITY("Velocity"), - KILLAURA("KillAura"); - - private final String spartan; - - CheatType(String spartan) { - this.spartan = spartan; - } - - public String toSpartan() { - return spartan; - } -} diff --git a/src/main/java/net/Indyuce/mmocore/comp/anticheat/SpartanPlugin.java b/src/main/java/net/Indyuce/mmocore/comp/anticheat/SpartanPlugin.java deleted file mode 100644 index d1849e2d..00000000 --- a/src/main/java/net/Indyuce/mmocore/comp/anticheat/SpartanPlugin.java +++ /dev/null @@ -1,21 +0,0 @@ -package net.Indyuce.mmocore.comp.anticheat; - -import java.util.Map; -import java.util.Map.Entry; - -import org.bukkit.entity.Player; - -import me.vagdedes.spartan.api.API; -import me.vagdedes.spartan.system.Enums.HackType; - -public class SpartanPlugin extends AntiCheatSupport { - @Override - public void disableAntiCheat(Player player, Map map) { - for(Entry entry : map.entrySet()) - API.cancelCheck(player, fromCheatType(entry.getKey()), entry.getValue()); - } - - private HackType fromCheatType(CheatType ct) { - return HackType.valueOf(ct.toSpartan()); - } -} diff --git a/src/main/java/net/Indyuce/mmocore/comp/mythicmobs/MythicHook.java b/src/main/java/net/Indyuce/mmocore/comp/mythicmobs/MythicHook.java index 72e8051a..f680b621 100644 --- a/src/main/java/net/Indyuce/mmocore/comp/mythicmobs/MythicHook.java +++ b/src/main/java/net/Indyuce/mmocore/comp/mythicmobs/MythicHook.java @@ -10,9 +10,10 @@ import net.Indyuce.mmocore.api.player.attribute.PlayerAttribute; import net.Indyuce.mmocore.api.player.attribute.PlayerAttributes; import net.Indyuce.mmocore.comp.mythicmobs.load.CurrencyItemDrop; import net.Indyuce.mmocore.comp.mythicmobs.load.GoldPouchDrop; -import net.Indyuce.mmocore.skill.Skill; +import net.Indyuce.mmocore.skill.RegisteredSkill; import org.apache.commons.lang.Validate; import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import java.util.Optional; @@ -39,23 +40,14 @@ public class MythicHook implements Listener { event.register(new CurrencyItemDrop("NOTE", event.getConfig())); } - @EventHandler + @EventHandler(priority = EventPriority.HIGH) public void b(MythicReloadedEvent event) { // When MM is reloaded, reload placeholders because they are no longer registered registerPlaceholders(); - // Reload MMOCore skills as well - for (Skill skill : MMOCore.plugin.skillManager.getActive()) - if (skill instanceof MythicSkill) - try { - String skillId = ((MythicSkill) skill).getSkill().getInternalName(); - Optional opt = MythicMobs.inst().getSkillManager().getSkill(skillId); - Validate.isTrue(opt.isPresent(), "Could not find skill with ID '" + skillId + "'"); - ((MythicSkill) skill).setSkill(opt.get()); - } catch (RuntimeException exception) { - MMOCore.log(Level.WARNING, "Could not reload MM skill '" + skill.getId() + "': " + exception.getMessage()); - } + // Reload skills + MMOCore.plugin.skillManager.initialize(true); } private void registerPlaceholders() { diff --git a/src/main/java/net/Indyuce/mmocore/comp/mythicmobs/MythicSkill.java b/src/main/java/net/Indyuce/mmocore/comp/mythicmobs/MythicSkill.java deleted file mode 100644 index 67f55ad6..00000000 --- a/src/main/java/net/Indyuce/mmocore/comp/mythicmobs/MythicSkill.java +++ /dev/null @@ -1,218 +0,0 @@ -package net.Indyuce.mmocore.comp.mythicmobs; - -import io.lumine.mythic.lib.api.player.EquipmentSlot; -import io.lumine.mythic.lib.api.stat.modifier.ModifierSource; -import io.lumine.mythic.lib.api.util.EnumUtils; -import io.lumine.mythic.lib.player.cooldown.CooldownInfo; -import io.lumine.mythic.lib.skill.trigger.PassiveSkill; -import io.lumine.mythic.lib.skill.trigger.TriggerMetadata; -import io.lumine.mythic.lib.skill.trigger.TriggerType; -import io.lumine.mythic.lib.skill.trigger.TriggeredSkill; -import io.lumine.xikage.mythicmobs.MythicMobs; -import io.lumine.xikage.mythicmobs.adapters.AbstractEntity; -import io.lumine.xikage.mythicmobs.adapters.AbstractLocation; -import io.lumine.xikage.mythicmobs.adapters.bukkit.BukkitAdapter; -import io.lumine.xikage.mythicmobs.mobs.GenericCaster; -import io.lumine.xikage.mythicmobs.skills.SkillCaster; -import io.lumine.xikage.mythicmobs.skills.SkillTrigger; -import net.Indyuce.mmocore.MMOCore; -import net.Indyuce.mmocore.api.event.PlayerPostCastSkillEvent; -import net.Indyuce.mmocore.api.event.PlayerPreCastSkillEvent; -import net.Indyuce.mmocore.api.event.PlayerResourceUpdateEvent; -import net.Indyuce.mmocore.api.player.PlayerData; -import net.Indyuce.mmocore.api.player.stats.StatType; -import net.Indyuce.mmocore.api.util.MMOCoreUtils; -import net.Indyuce.mmocore.api.util.math.formula.IntegerLinearValue; -import net.Indyuce.mmocore.api.util.math.formula.LinearValue; -import net.Indyuce.mmocore.comp.anticheat.CheatType; -import net.Indyuce.mmocore.skill.CasterMetadata; -import net.Indyuce.mmocore.skill.Skill; -import net.Indyuce.mmocore.skill.metadata.SkillMetadata; -import org.apache.commons.lang.Validate; -import org.bukkit.Bukkit; -import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.configuration.file.FileConfiguration; -import org.jetbrains.annotations.NotNull; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Optional; -import java.util.logging.Level; - -public class MythicSkill extends Skill implements TriggeredSkill { - private final Map antiCheat = new HashMap<>(); - private final PassiveSkill mythicLibSkill; - - // Not final so that it can be changed when MM is reloaded - private io.lumine.xikage.mythicmobs.skills.Skill skill; - - public MythicSkill(String id, FileConfiguration config) { - super(id); - - String mmId = config.getString("mythicmobs-skill-id"); - Validate.notNull(mmId, "Could not find MM skill ID"); - - Optional opt = MythicMobs.inst().getSkillManager().getSkill(mmId); - Validate.isTrue(opt.isPresent(), "Could not find MM skill " + mmId); - skill = opt.get(); - - String format = config.getString("material"); - Validate.notNull(format, "Could not load skill material"); - setIcon(MMOCoreUtils.readIcon(format)); - - setName(config.getString("name")); - setLore(config.getStringList("lore")); - - for (String key : config.getKeys(false)) { - Object mod = config.get(key); - if (mod instanceof ConfigurationSection) - addModifier(key, readLinearValue((ConfigurationSection) mod)); - } - - if (config.isConfigurationSection("disable-anti-cheat")) - for (String key : config.getKeys(false)) { - Optional cheatType = EnumUtils.getIfPresent(CheatType.class, key.toUpperCase()); - if (cheatType.isPresent() && config.isInt("disable-anti-cheat." + key)) - antiCheat.put(cheatType.get(), config.getInt("disable-anti-cheat." + key)); - else - MMOCore.log(Level.WARNING, "Invalid Anti-Cheat configuration for '" + id + "'!"); - } - - if (config.isString("passive-type")) { - Optional passiveType = EnumUtils.getIfPresent(TriggerType.class, config.getString("passive-type").toUpperCase()); - Validate.isTrue(passiveType.isPresent(), "Invalid passive skill type"); - setPassive(); - mythicLibSkill = new PassiveSkill("MMOCorePassiveSkill", passiveType.get(), this, EquipmentSlot.OTHER, ModifierSource.OTHER); - } else - mythicLibSkill = null; - } - - public Map getAntiCheat() { - return antiCheat; - } - - public io.lumine.xikage.mythicmobs.skills.Skill getSkill() { - return skill; - } - - /** - * Used when reloading MMOCore. Something convenient to do is to - * reload the MMOCore skills that are linked to a MM skill whenever - * MM is reloaded, so that changes to the skill are taken into account - * in MMOCore skills. - * - * @param skill Newest version of skill - */ - public void setSkill(@NotNull io.lumine.xikage.mythicmobs.skills.Skill skill) { - Validate.notNull(skill); - this.skill = skill; - } - - public PassiveSkill toMythicLib() { - return mythicLibSkill; - } - - @Override - public SkillMetadata whenCast(CasterMetadata caster, SkillInfo skill) { - SkillMetadata cast = new SkillMetadata(caster, skill); - if (isPassive() || !cast.isSuccessful()) - return cast; - - // Gather MythicMobs skill info - HashSet targetEntities = new HashSet<>(); - HashSet targetLocations = new HashSet<>(); - - AbstractEntity trigger = BukkitAdapter.adapt(caster.getPlayer()); - SkillCaster skillCaster = new GenericCaster(trigger); - io.lumine.xikage.mythicmobs.skills.SkillMetadata skillMeta = new io.lumine.xikage.mythicmobs.skills.SkillMetadata(SkillTrigger.CAST, skillCaster, trigger, BukkitAdapter.adapt(caster.getPlayer().getLocation()), targetEntities, targetLocations, 1); - - // Disable anticheat - if (MMOCore.plugin.hasAntiCheat()) - MMOCore.plugin.antiCheatSupport.disableAntiCheat(caster.getPlayer(), antiCheat); - - // Place cast skill info in a variable - skillMeta.getVariables().putObject("MMOSkill", cast); - skillMeta.getVariables().putObject("MMOStatMap", caster.getStats()); - - // Yo is that me or the second argument is f***ing useless - if (this.skill.usable(skillMeta, SkillTrigger.CAST)) - this.skill.execute(skillMeta); - else - cast.abort(); - - return cast; - } - - /** - * Used to load double modifiers from the config with a specific type, since - * modifiers have initially a type for mmocore default skills - */ - private LinearValue readLinearValue(ConfigurationSection section) { - return section.getBoolean("int") ? new IntegerLinearValue(section) : new LinearValue(section); - } - - @Override - public void execute(TriggerMetadata triggerMeta) { - PlayerData playerData = PlayerData.get(triggerMeta.getAttack().getPlayer().getUniqueId()); - if (!playerData.getProfess().hasSkill(this)) - return; - - // Check for Bukkit pre cast event - Skill.SkillInfo skill = playerData.getProfess().getSkill(this); - PlayerPreCastSkillEvent preEvent = new PlayerPreCastSkillEvent(playerData, skill); - Bukkit.getPluginManager().callEvent(preEvent); - if (preEvent.isCancelled()) - return; - - // Gather MMOCore skill info - CasterMetadata caster = new CasterMetadata(playerData); - SkillMetadata cast = new SkillMetadata(caster, skill); - if (!cast.isSuccessful()) - return; - - // Gather MythicMobs skill info - HashSet targetEntities = new HashSet<>(); - HashSet targetLocations = new HashSet<>(); - - // The only difference - if (triggerMeta.getTarget() != null) - targetEntities.add(BukkitAdapter.adapt(triggerMeta.getTarget())); - - AbstractEntity trigger = BukkitAdapter.adapt(caster.getPlayer()); - SkillCaster skillCaster = new GenericCaster(trigger); - io.lumine.xikage.mythicmobs.skills.SkillMetadata skillMeta = new io.lumine.xikage.mythicmobs.skills.SkillMetadata(SkillTrigger.API, skillCaster, trigger, BukkitAdapter.adapt(caster.getPlayer().getEyeLocation()), targetEntities, targetLocations, 1); - - // Check if the MythicMobs skill can be cast - if (!this.skill.usable(skillMeta, SkillTrigger.CAST)) { - cast.abort(); - return; - } - - // Disable anticheat - if (MMOCore.plugin.hasAntiCheat()) - MMOCore.plugin.antiCheatSupport.disableAntiCheat(caster.getPlayer(), antiCheat); - - // Place cast skill info in a variable - skillMeta.getVariables().putObject("MMOSkill", cast); - skillMeta.getVariables().putObject("MMOStatMap", caster.getStats()); - - // Apply cooldown, mana and stamina costs - if (!playerData.noCooldown) { - - // Cooldown - double flatCooldownReduction = Math.max(0, Math.min(1, playerData.getStats().getStat(StatType.COOLDOWN_REDUCTION) / 100)); - CooldownInfo cooldownHandler = playerData.getCooldownMap().applyCooldown(cast.getSkill(), cast.getCooldown()); - cooldownHandler.reduceInitialCooldown(flatCooldownReduction); - - // Mana and stamina cost - playerData.giveMana(-cast.getManaCost(), PlayerResourceUpdateEvent.UpdateReason.SKILL_COST); - playerData.giveStamina(-cast.getStaminaCost(), PlayerResourceUpdateEvent.UpdateReason.SKILL_COST); - } - - // Execute the MythicMobs skill - this.skill.execute(skillMeta); - - Bukkit.getPluginManager().callEvent(new PlayerPostCastSkillEvent(playerData, skill, cast)); - } -} diff --git a/src/main/java/net/Indyuce/mmocore/comp/placeholder/RPGPlaceholders.java b/src/main/java/net/Indyuce/mmocore/comp/placeholder/RPGPlaceholders.java index e047842e..f1c52ebc 100644 --- a/src/main/java/net/Indyuce/mmocore/comp/placeholder/RPGPlaceholders.java +++ b/src/main/java/net/Indyuce/mmocore/comp/placeholder/RPGPlaceholders.java @@ -9,7 +9,7 @@ import net.Indyuce.mmocore.api.player.stats.StatType; import net.Indyuce.mmocore.api.quest.PlayerQuests; import net.Indyuce.mmocore.experience.PlayerProfessions; import net.Indyuce.mmocore.experience.Profession; -import net.Indyuce.mmocore.skill.Skill; +import net.Indyuce.mmocore.skill.RegisteredSkill; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.OfflinePlayer; @@ -61,7 +61,7 @@ public class RPGPlaceholders extends PlaceholderExpansion { else if (identifier.startsWith("skill_level_")) { String id = identifier.substring(12); - Skill skill = Objects.requireNonNull(MMOCore.plugin.skillManager.get(id), "Could not find skill with ID '" + id + "'"); + RegisteredSkill skill = Objects.requireNonNull(MMOCore.plugin.skillManager.getSkill(id), "Could not find skill with ID '" + id + "'"); return String.valueOf(playerData.getSkillLevel(skill)); } diff --git a/src/main/java/net/Indyuce/mmocore/experience/Profession.java b/src/main/java/net/Indyuce/mmocore/experience/Profession.java index 39f4659f..5e21b814 100644 --- a/src/main/java/net/Indyuce/mmocore/experience/Profession.java +++ b/src/main/java/net/Indyuce/mmocore/experience/Profession.java @@ -25,10 +25,7 @@ public class Profession { /** * Experience given to the main player level whenever he levels up this profession - * - * @deprecated Being replaced by {@link ExperienceTable} */ - @Deprecated private final LinearValue experience; public Profession(String id, FileConfiguration config) { @@ -111,10 +108,6 @@ public class Profession { return maxLevel > 0; } - public int calculateExperience(int x) { - return (int) experience.calculate(x); - } - public LinearValue getExperience() { return experience; } diff --git a/src/main/java/net/Indyuce/mmocore/gui/SkillList.java b/src/main/java/net/Indyuce/mmocore/gui/SkillList.java index e5e2ba01..fe98c1f4 100644 --- a/src/main/java/net/Indyuce/mmocore/gui/SkillList.java +++ b/src/main/java/net/Indyuce/mmocore/gui/SkillList.java @@ -5,14 +5,14 @@ import io.lumine.mythic.lib.api.item.ItemTag; import io.lumine.mythic.lib.api.item.NBTItem; import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.api.player.PlayerData; -import net.Indyuce.mmocore.skill.Skill; -import net.Indyuce.mmocore.skill.Skill.SkillInfo; import net.Indyuce.mmocore.api.util.MMOCoreUtils; import net.Indyuce.mmocore.gui.api.EditableInventory; import net.Indyuce.mmocore.gui.api.GeneratedInventory; import net.Indyuce.mmocore.gui.api.item.InventoryItem; import net.Indyuce.mmocore.gui.api.item.Placeholders; import net.Indyuce.mmocore.gui.api.item.SimplePlaceholderItem; +import net.Indyuce.mmocore.skill.ClassSkill; +import net.Indyuce.mmocore.skill.RegisteredSkill; import org.apache.commons.lang.Validate; import org.bukkit.ChatColor; import org.bukkit.Material; @@ -28,385 +28,383 @@ import java.util.ArrayList; import java.util.List; public class SkillList extends EditableInventory { - public SkillList() { - super("skill-list"); - } - - @Override - public InventoryItem load(String function, ConfigurationSection config) { - - if (function.equals("skill")) - return new SkillItem(config); - - if (function.equals("switch")) - return new SwitchItem(config); - - if (function.equals("level")) - return new LevelItem(config); - - if (function.equals("upgrade")) - return new InventoryItem(config) { - - @Override - public Placeholders getPlaceholders(SkillViewerInventory inv, int n) { - Skill selected = inv.selected.getSkill(); - Placeholders holders = new Placeholders(); - - holders.register("skill_caps", selected.getName().toUpperCase()); - holders.register("skill", selected.getName()); - holders.register("skill_points", "" + inv.getPlayerData().getSkillPoints()); - - return holders; - } - - @Override - public boolean canDisplay(SkillViewerInventory inv) { - return !inv.binding; - } - }; - - if (function.equals("slot")) - return new InventoryItem(config) { - private final String none = MythicLib.plugin.parseColors(config.getString("no-skill")); - private final Material emptyMaterial = Material - .valueOf(config.getString("empty-item").toUpperCase().replace("-", "_").replace(" ", "_")); - private final int emptyCMD = config.getInt("empty-custom-model-data", getModelData()); - - @Override - public Placeholders getPlaceholders(SkillViewerInventory inv, int n) { - Skill selected = inv.selected.getSkill(); - Skill skill = inv.getPlayerData().hasSkillBound(n) ? inv.getPlayerData().getBoundSkill(n).getSkill() : null; - - Placeholders holders = new Placeholders(); - - holders.register("skill", skill == null ? none : skill.getName()); - holders.register("index", "" + (n + 1)); - holders.register("slot", MMOCoreUtils.intToRoman(n + 1)); - holders.register("selected", selected.getName()); - - return holders; - } - - @Override - public ItemStack display(SkillViewerInventory inv, int n) { - ItemStack item = super.display(inv, n); - if (!inv.getPlayerData().hasSkillBound(n)) { - item.setType(emptyMaterial); - - if (MythicLib.plugin.getVersion().isStrictlyHigher(1, 13)) { - ItemMeta meta = item.getItemMeta(); - meta.setCustomModelData(emptyCMD); - item.setItemMeta(meta); - } - } - return item; - } - - @Override - public boolean canDisplay(SkillViewerInventory inv) { - return inv.binding; - } - - @Override - public boolean hasDifferentDisplay() { - return true; - } - }; - - return new SimplePlaceholderItem(config); - } - - public GeneratedInventory newInventory(PlayerData data) { - return new SkillViewerInventory(data, this); - } - - public class SwitchItem extends SimplePlaceholderItem { - private final SimplePlaceholderItem binding, upgrading; - - public SwitchItem(ConfigurationSection config) { - super(config); - - Validate.isTrue(config.contains("binding"), "Config must have 'binding'"); - Validate.isTrue(config.contains("upgrading"), "Config must have 'upgrading'"); - - binding = new SimplePlaceholderItem(config.getConfigurationSection("binding")); - upgrading = new SimplePlaceholderItem(config.getConfigurationSection("upgrading")); - } - - @Override - public ItemStack display(SkillViewerInventory inv, int n) { - return inv.binding ? upgrading.display(inv) : binding.display(inv); - } - - @Override - public boolean canDisplay(SkillViewerInventory inv) { - return true; - } - } - - public class LevelItem extends InventoryItem { - private final int offset; - - public LevelItem(ConfigurationSection config) { - super(config); - - offset = config.getInt("offset"); - } - - @Override - public boolean hasDifferentDisplay() { - return true; - } - - @Override - public ItemStack display(SkillViewerInventory inv, int n) { - - SkillInfo skill = inv.selected; - int skillLevel = inv.getPlayerData().getSkillLevel(skill.getSkill()) + n - offset; - if (skillLevel < 1) - return new ItemStack(Material.AIR); - - List lore = new ArrayList<>(getLore()); - int index = lore.indexOf("{lore}"); - lore.remove(index); - List skillLore = skill.calculateLore(inv.getPlayerData(), skillLevel); - for (int j = 0; j < skillLore.size(); j++) - lore.add(index + j, skillLore.get(j)); - - for (int j = 0; j < lore.size(); j++) - lore.set(j, ChatColor.GRAY + MythicLib.plugin.parseColors(lore.get(j))); - - ItemStack item = new ItemStack(getMaterial()); - ItemMeta meta = item.getItemMeta(); - meta.setDisplayName(MythicLib.plugin.parseColors(getName().replace("{skill}", skill.getSkill().getName()) - .replace("{roman}", MMOCoreUtils.intToRoman(skillLevel)).replace("{level}", "" + skillLevel))); - meta.addItemFlags(ItemFlag.values()); - meta.setLore(lore); - if (MythicLib.plugin.getVersion().isStrictlyHigher(1, 13)) - meta.setCustomModelData(getModelData()); - item.setItemMeta(meta); - - return NBTItem.get(item).addTag(new ItemTag("skillId", skill.getSkill().getId())).toItem(); - } - - @Override - public Placeholders getPlaceholders(SkillViewerInventory inv, int n) { - return new Placeholders(); - } - - @Override - public boolean canDisplay(SkillViewerInventory inv) { - return !inv.binding; - } - } - - public class SkillItem extends InventoryItem { - private final int selectedSkillSlot; - - public SkillItem(ConfigurationSection config) { - super(Material.BARRIER, config); - - selectedSkillSlot = config.getInt("selected-slot"); - } - - @Override - public boolean hasDifferentDisplay() { - return true; - } - - @Override - public ItemStack display(SkillViewerInventory inv, int n) { - - /* - * calculate placeholders - */ - SkillInfo skill = inv.skills.get(mod(n + inv.getPlayerData().skillGuiDisplayOffset, inv.skills.size())); - Placeholders holders = getPlaceholders(inv.getPlayerData(), skill); - - List lore = new ArrayList<>(getLore()); - - int index = lore.indexOf("{lore}"); - lore.remove(index); - List skillLore = skill.calculateLore(inv.getPlayerData()); - for (int j = 0; j < skillLore.size(); j++) - lore.add(index + j, skillLore.get(j)); - - boolean unlocked = skill.getUnlockLevel() <= inv.getPlayerData().getLevel(); - - lore.removeIf(next -> (next.startsWith("{unlocked}") && !unlocked) || (next.startsWith("{locked}") && unlocked) || (next.startsWith("{max_level}") && (!skill.hasMaxLevel() || skill.getMaxLevel() > inv.getPlayerData().getSkillLevel(skill.getSkill())))); - - for (int j = 0; j < lore.size(); j++) - lore.set(j, ChatColor.GRAY + holders.apply(inv.getPlayer(), lore.get(j))); - - /* - * generate item - */ - ItemStack item = skill.getSkill().getIcon(); - ItemMeta meta = item.getItemMeta(); - meta.setDisplayName(holders.apply(inv.getPlayer(), getName())); - meta.addItemFlags(ItemFlag.values()); - meta.setLore(lore); - item.setItemMeta(meta); - - return NBTItem.get(item).addTag(new ItemTag("skillId", skill.getSkill().getId())).toItem(); - } - - public Placeholders getPlaceholders(PlayerData player, SkillInfo skill) { - Placeholders holders = new Placeholders(); - holders.register("skill", skill.getSkill().getName()); - holders.register("unlock", "" + skill.getUnlockLevel()); - holders.register("level", "" + player.getSkillLevel(skill.getSkill())); - return holders; - } - - @Override - public Placeholders getPlaceholders(SkillViewerInventory inv, int n) { - return new Placeholders(); - } - } - - public class SkillViewerInventory extends GeneratedInventory { - - /* - * cached information - */ - private final List skills; - private final List skillSlots; - private final List slotSlots; - - private boolean binding; - private SkillInfo selected; - - public SkillViewerInventory(PlayerData playerData, EditableInventory editable) { - super(playerData, editable); - - skills = new ArrayList<>(playerData.getProfess().getSkills()); - skillSlots = getEditable().getByFunction("skill").getSlots(); - slotSlots = getEditable().getByFunction("slot").getSlots(); - } - - @Override - public String calculateName() { - return getName(); - } - - @Override - public void open() { - int selectedSkillSlot = ((SkillItem) getEditable().getByFunction("skill")).selectedSkillSlot; - selected = skills.get(mod(selectedSkillSlot + playerData.skillGuiDisplayOffset, skills.size())); - - super.open(); - } - - @Override - public void whenClicked(InventoryClickEvent event, InventoryItem item) { - - if (skillSlots.contains(event.getRawSlot()) - && event.getRawSlot() != ((SkillItem) getEditable().getByFunction("skill")).selectedSkillSlot) { - player.playSound(player.getLocation(), Sound.UI_BUTTON_CLICK, 1, 2); - playerData.skillGuiDisplayOffset = (playerData.skillGuiDisplayOffset + (event.getRawSlot() - 13)) % skills.size(); - open(); - return; - } - - if (item.getFunction().equals("previous")) { - player.playSound(player.getLocation(), Sound.UI_BUTTON_CLICK, 1, 2); - playerData.skillGuiDisplayOffset = (playerData.skillGuiDisplayOffset - 1) % skills.size(); - open(); - return; - } - - if (item.getFunction().equals("next")) { - player.playSound(player.getLocation(), Sound.UI_BUTTON_CLICK, 1, 2); - playerData.skillGuiDisplayOffset = (playerData.skillGuiDisplayOffset + 1) % skills.size(); - open(); - return; - } - - if (item.getFunction().equals("switch")) { - player.playSound(player.getLocation(), Sound.UI_BUTTON_CLICK, 1, 2); - binding = !binding; - open(); - return; - } - - /* - * binding or unbinding skills. - */ - if (binding) { - for (int index = 0; index < slotSlots.size(); index++) { - int slot = slotSlots.get(index); - if (event.getRawSlot() == slot) { - - // unbind if there is a current spell. - if (event.getAction() == InventoryAction.PICKUP_HALF) { - if (!playerData.hasSkillBound(index)) { - MMOCore.plugin.configManager.getSimpleMessage("no-skill-bound").send(player); - player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 2); - return; - } - - player.playSound(player.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1, 2); - playerData.unbindSkill(index); - open(); - return; - } - - if (selected == null) - return; - - if (selected.getSkill().isPassive()) { - MMOCore.plugin.configManager.getSimpleMessage("not-active-skill").send(player); - player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 2); - return; - } - - if (!playerData.hasSkillUnlocked(selected)) { - MMOCore.plugin.configManager.getSimpleMessage("not-unlocked-skill").send(player); - player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 2); - return; - } - - player.playSound(player.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1, 2); - playerData.setBoundSkill(index, selected); - open(); - return; - } - } - - /* - * upgrading a player skill - */ - } else if (item.getFunction().equals("upgrade")) { - if (!playerData.hasSkillUnlocked(selected)) { - MMOCore.plugin.configManager.getSimpleMessage("not-unlocked-skill").send(player); - player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 2); - return; - } - - if (playerData.getSkillPoints() < 1) { - MMOCore.plugin.configManager.getSimpleMessage("not-enough-skill-points").send(player); - player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 2); - return; - } - - if (selected.hasMaxLevel() && playerData.getSkillLevel(selected.getSkill()) >= selected.getMaxLevel()) { - MMOCore.plugin.configManager.getSimpleMessage("skill-max-level-hit").send(player); - player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 2); - return; - } - - playerData.giveSkillPoints(-1); - playerData.setSkillLevel(selected.getSkill(), playerData.getSkillLevel(selected.getSkill()) + 1); - MMOCore.plugin.configManager.getSimpleMessage("upgrade-skill", "skill", selected.getSkill().getName(), "level", - "" + playerData.getSkillLevel(selected.getSkill())).send(player); - player.playSound(player.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 1, 2); - open(); - } - } - } - - private int mod(int x, int n) { - return x < 0 ? (x + n) : (x % n); - } + public SkillList() { + super("skill-list"); + } + + @Override + public InventoryItem load(String function, ConfigurationSection config) { + + if (function.equals("skill")) + return new SkillItem(config); + + if (function.equals("switch")) + return new SwitchItem(config); + + if (function.equals("level")) + return new LevelItem(config); + + if (function.equals("upgrade")) + return new InventoryItem(config) { + + @Override + public Placeholders getPlaceholders(SkillViewerInventory inv, int n) { + RegisteredSkill selected = inv.selected.getSkill(); + Placeholders holders = new Placeholders(); + + holders.register("skill_caps", selected.getName().toUpperCase()); + holders.register("skill", selected.getName()); + holders.register("skill_points", "" + inv.getPlayerData().getSkillPoints()); + + return holders; + } + + @Override + public boolean canDisplay(SkillViewerInventory inv) { + return !inv.binding; + } + }; + + if (function.equals("slot")) + return new InventoryItem(config) { + private final String none = MythicLib.plugin.parseColors(config.getString("no-skill")); + private final Material emptyMaterial = Material + .valueOf(config.getString("empty-item").toUpperCase().replace("-", "_").replace(" ", "_")); + private final int emptyCMD = config.getInt("empty-custom-model-data", getModelData()); + + @Override + public Placeholders getPlaceholders(SkillViewerInventory inv, int n) { + RegisteredSkill selected = inv.selected.getSkill(); + RegisteredSkill skill = inv.getPlayerData().hasSkillBound(n) ? inv.getPlayerData().getBoundSkill(n).getSkill() : null; + + Placeholders holders = new Placeholders(); + + holders.register("skill", skill == null ? none : skill.getName()); + holders.register("index", "" + (n + 1)); + holders.register("slot", MMOCoreUtils.intToRoman(n + 1)); + holders.register("selected", selected.getName()); + + return holders; + } + + @Override + public ItemStack display(SkillViewerInventory inv, int n) { + ItemStack item = super.display(inv, n); + if (!inv.getPlayerData().hasSkillBound(n)) { + item.setType(emptyMaterial); + + if (MythicLib.plugin.getVersion().isStrictlyHigher(1, 13)) { + ItemMeta meta = item.getItemMeta(); + meta.setCustomModelData(emptyCMD); + item.setItemMeta(meta); + } + } + return item; + } + + @Override + public boolean canDisplay(SkillViewerInventory inv) { + return inv.binding; + } + + @Override + public boolean hasDifferentDisplay() { + return true; + } + }; + + return new SimplePlaceholderItem(config); + } + + public GeneratedInventory newInventory(PlayerData data) { + return new SkillViewerInventory(data, this); + } + + public class SwitchItem extends SimplePlaceholderItem { + private final SimplePlaceholderItem binding, upgrading; + + public SwitchItem(ConfigurationSection config) { + super(config); + + Validate.isTrue(config.contains("binding"), "Config must have 'binding'"); + Validate.isTrue(config.contains("upgrading"), "Config must have 'upgrading'"); + + binding = new SimplePlaceholderItem(config.getConfigurationSection("binding")); + upgrading = new SimplePlaceholderItem(config.getConfigurationSection("upgrading")); + } + + @Override + public ItemStack display(SkillViewerInventory inv, int n) { + return inv.binding ? upgrading.display(inv) : binding.display(inv); + } + + @Override + public boolean canDisplay(SkillViewerInventory inv) { + return true; + } + } + + public class LevelItem extends InventoryItem { + private final int offset; + + public LevelItem(ConfigurationSection config) { + super(config); + + offset = config.getInt("offset"); + } + + @Override + public boolean hasDifferentDisplay() { + return true; + } + + @Override + public ItemStack display(SkillViewerInventory inv, int n) { + + ClassSkill skill = inv.selected; + int skillLevel = inv.getPlayerData().getSkillLevel(skill.getSkill()) + n - offset; + if (skillLevel < 1) + return new ItemStack(Material.AIR); + + List lore = new ArrayList<>(getLore()); + int index = lore.indexOf("{lore}"); + lore.remove(index); + List skillLore = skill.calculateLore(inv.getPlayerData(), skillLevel); + for (int j = 0; j < skillLore.size(); j++) + lore.add(index + j, skillLore.get(j)); + + for (int j = 0; j < lore.size(); j++) + lore.set(j, ChatColor.GRAY + MythicLib.plugin.parseColors(lore.get(j))); + + ItemStack item = new ItemStack(getMaterial()); + ItemMeta meta = item.getItemMeta(); + meta.setDisplayName(MythicLib.plugin.parseColors(getName().replace("{skill}", skill.getSkill().getName()) + .replace("{roman}", MMOCoreUtils.intToRoman(skillLevel)).replace("{level}", "" + skillLevel))); + meta.addItemFlags(ItemFlag.values()); + meta.setLore(lore); + if (MythicLib.plugin.getVersion().isStrictlyHigher(1, 13)) + meta.setCustomModelData(getModelData()); + item.setItemMeta(meta); + + return NBTItem.get(item).addTag(new ItemTag("skillId", skill.getSkill().getHandler().getId())).toItem(); + } + + @Override + public Placeholders getPlaceholders(SkillViewerInventory inv, int n) { + return new Placeholders(); + } + + @Override + public boolean canDisplay(SkillViewerInventory inv) { + return !inv.binding; + } + } + + public class SkillItem extends InventoryItem { + private final int selectedSkillSlot; + + public SkillItem(ConfigurationSection config) { + super(Material.BARRIER, config); + + selectedSkillSlot = config.getInt("selected-slot"); + } + + @Override + public boolean hasDifferentDisplay() { + return true; + } + + @Override + public ItemStack display(SkillViewerInventory inv, int n) { + + /* + * calculate placeholders + */ + ClassSkill skill = inv.skills.get(mod(n + inv.getPlayerData().skillGuiDisplayOffset, inv.skills.size())); + Placeholders holders = getPlaceholders(inv.getPlayerData(), skill); + + List lore = new ArrayList<>(getLore()); + + int index = lore.indexOf("{lore}"); + lore.remove(index); + List skillLore = skill.calculateLore(inv.getPlayerData()); + for (int j = 0; j < skillLore.size(); j++) + lore.add(index + j, skillLore.get(j)); + + boolean unlocked = skill.getUnlockLevel() <= inv.getPlayerData().getLevel(); + + lore.removeIf(next -> (next.startsWith("{unlocked}") && !unlocked) || (next.startsWith("{locked}") && unlocked) || (next.startsWith("{max_level}") && (!skill.hasMaxLevel() || skill.getMaxLevel() > inv.getPlayerData().getSkillLevel(skill.getSkill())))); + + for (int j = 0; j < lore.size(); j++) + lore.set(j, ChatColor.GRAY + holders.apply(inv.getPlayer(), lore.get(j))); + + /* + * generate item + */ + ItemStack item = skill.getSkill().getIcon(); + ItemMeta meta = item.getItemMeta(); + meta.setDisplayName(holders.apply(inv.getPlayer(), getName())); + meta.addItemFlags(ItemFlag.values()); + meta.setLore(lore); + item.setItemMeta(meta); + + return NBTItem.get(item).addTag(new ItemTag("skillId", skill.getSkill().getHandler().getId())).toItem(); + } + + public Placeholders getPlaceholders(PlayerData player, ClassSkill skill) { + Placeholders holders = new Placeholders(); + holders.register("skill", skill.getSkill().getName()); + holders.register("unlock", "" + skill.getUnlockLevel()); + holders.register("level", "" + player.getSkillLevel(skill.getSkill())); + return holders; + } + + @Override + public Placeholders getPlaceholders(SkillViewerInventory inv, int n) { + return new Placeholders(); + } + } + + public class SkillViewerInventory extends GeneratedInventory { + + // Cached information + private final List skills; + private final List skillSlots; + private final List slotSlots; + + private boolean binding; + private ClassSkill selected; + + public SkillViewerInventory(PlayerData playerData, EditableInventory editable) { + super(playerData, editable); + + skills = new ArrayList<>(playerData.getProfess().getSkills()); + skillSlots = getEditable().getByFunction("skill").getSlots(); + slotSlots = getEditable().getByFunction("slot").getSlots(); + } + + @Override + public String calculateName() { + return getName(); + } + + @Override + public void open() { + int selectedSkillSlot = ((SkillItem) getEditable().getByFunction("skill")).selectedSkillSlot; + selected = skills.get(mod(selectedSkillSlot + playerData.skillGuiDisplayOffset, skills.size())); + + super.open(); + } + + @Override + public void whenClicked(InventoryClickEvent event, InventoryItem item) { + + if (skillSlots.contains(event.getRawSlot()) + && event.getRawSlot() != ((SkillItem) getEditable().getByFunction("skill")).selectedSkillSlot) { + player.playSound(player.getLocation(), Sound.UI_BUTTON_CLICK, 1, 2); + playerData.skillGuiDisplayOffset = (playerData.skillGuiDisplayOffset + (event.getRawSlot() - 13)) % skills.size(); + open(); + return; + } + + if (item.getFunction().equals("previous")) { + player.playSound(player.getLocation(), Sound.UI_BUTTON_CLICK, 1, 2); + playerData.skillGuiDisplayOffset = (playerData.skillGuiDisplayOffset - 1) % skills.size(); + open(); + return; + } + + if (item.getFunction().equals("next")) { + player.playSound(player.getLocation(), Sound.UI_BUTTON_CLICK, 1, 2); + playerData.skillGuiDisplayOffset = (playerData.skillGuiDisplayOffset + 1) % skills.size(); + open(); + return; + } + + if (item.getFunction().equals("switch")) { + player.playSound(player.getLocation(), Sound.UI_BUTTON_CLICK, 1, 2); + binding = !binding; + open(); + return; + } + + /* + * binding or unbinding skills. + */ + if (binding) { + for (int index = 0; index < slotSlots.size(); index++) { + int slot = slotSlots.get(index); + if (event.getRawSlot() == slot) { + + // unbind if there is a current spell. + if (event.getAction() == InventoryAction.PICKUP_HALF) { + if (!playerData.hasSkillBound(index)) { + MMOCore.plugin.configManager.getSimpleMessage("no-skill-bound").send(player); + player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 2); + return; + } + + player.playSound(player.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1, 2); + playerData.unbindSkill(index); + open(); + return; + } + + if (selected == null) + return; + + if (selected.getSkill().isPassive()) { + MMOCore.plugin.configManager.getSimpleMessage("not-active-skill").send(player); + player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 2); + return; + } + + if (!playerData.hasSkillUnlocked(selected)) { + MMOCore.plugin.configManager.getSimpleMessage("not-unlocked-skill").send(player); + player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 2); + return; + } + + player.playSound(player.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1, 2); + playerData.setBoundSkill(index, selected); + open(); + return; + } + } + + /* + * upgrading a player skill + */ + } else if (item.getFunction().equals("upgrade")) { + if (!playerData.hasSkillUnlocked(selected)) { + MMOCore.plugin.configManager.getSimpleMessage("not-unlocked-skill").send(player); + player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 2); + return; + } + + if (playerData.getSkillPoints() < 1) { + MMOCore.plugin.configManager.getSimpleMessage("not-enough-skill-points").send(player); + player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 2); + return; + } + + if (selected.hasMaxLevel() && playerData.getSkillLevel(selected.getSkill()) >= selected.getMaxLevel()) { + MMOCore.plugin.configManager.getSimpleMessage("skill-max-level-hit").send(player); + player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 2); + return; + } + + playerData.giveSkillPoints(-1); + playerData.setSkillLevel(selected.getSkill(), playerData.getSkillLevel(selected.getSkill()) + 1); + MMOCore.plugin.configManager.getSimpleMessage("upgrade-skill", "skill", selected.getSkill().getName(), "level", + "" + playerData.getSkillLevel(selected.getSkill())).send(player); + player.playSound(player.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 1, 2); + open(); + } + } + } + + private int mod(int x, int n) { + return x < 0 ? (x + n) : (x % n); + } } \ No newline at end of file diff --git a/src/main/java/net/Indyuce/mmocore/listener/BlockListener.java b/src/main/java/net/Indyuce/mmocore/listener/BlockListener.java index 5aeddc78..19e5f6b7 100644 --- a/src/main/java/net/Indyuce/mmocore/listener/BlockListener.java +++ b/src/main/java/net/Indyuce/mmocore/listener/BlockListener.java @@ -39,9 +39,7 @@ public class BlockListener implements Listener { String savedData = event.getBlock().getBlockData().getAsString(); Block block = event.getBlock(); - /* - * Check for custom mining in the current region first. - */ + // Check for custom mining in the current region first. boolean customMine = MMOCore.plugin.mineManager.isEnabled(player, block.getLocation()); if (!customMine) return; @@ -70,9 +68,7 @@ public class BlockListener implements Listener { return; } - /* - * Extra breaking conditions. - */ + // Extra breaking conditions. if (!info.getBlock().breakRestrictions(block)) { event.setCancelled(true); return; diff --git a/src/main/java/net/Indyuce/mmocore/listener/SpellCast.java b/src/main/java/net/Indyuce/mmocore/listener/SpellCast.java index 178a568d..31017c64 100644 --- a/src/main/java/net/Indyuce/mmocore/listener/SpellCast.java +++ b/src/main/java/net/Indyuce/mmocore/listener/SpellCast.java @@ -1,10 +1,13 @@ package net.Indyuce.mmocore.listener; +import io.lumine.mythic.lib.api.player.EquipmentSlot; +import io.lumine.mythic.lib.player.PlayerMetadata; +import io.lumine.mythic.lib.skill.trigger.TriggerMetadata; import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.manager.ConfigManager; import net.Indyuce.mmocore.manager.SoundManager; -import net.Indyuce.mmocore.skill.Skill.SkillInfo; +import net.Indyuce.mmocore.skill.ClassSkill; import org.bukkit.Bukkit; import org.bukkit.GameMode; import org.bukkit.entity.Player; @@ -80,7 +83,7 @@ public class SpellCast implements Listener { return; /* - * when the event is cancelled, another playerItemHeldEvent is + * When the event is cancelled, another playerItemHeldEvent is * called and previous and next slots are equal. the event must not * listen to that non-player called event. */ @@ -91,12 +94,14 @@ public class SpellCast implements Listener { int slot = event.getNewSlot() + (event.getNewSlot() >= player.getInventory().getHeldItemSlot() ? -1 : 0); /* - * the event is called again soon after the first since when + * The event is called again soon after the first since when * cancelling the first one, the player held item slot must go back * to the previous one. */ - if (slot >= 0 && playerData.hasSkillBound(slot)) - playerData.cast(playerData.getBoundSkill(slot)); + if (slot >= 0 && playerData.hasSkillBound(slot)) { + PlayerMetadata caster = playerData.getMMOPlayerData().getStatMap().cache(EquipmentSlot.MAIN_HAND); + playerData.getBoundSkill(slot).toCastable(playerData).cast(new TriggerMetadata(caster, null, null)); + } } @EventHandler @@ -123,9 +128,9 @@ public class SpellCast implements Listener { StringBuilder str = new StringBuilder(); if (!data.isOnline()) return str.toString(); for (int j = 0; j < data.getBoundSkills().size(); j++) { - SkillInfo skill = data.getBoundSkill(j); + ClassSkill skill = data.getBoundSkill(j); str.append((str.length() == 0) ? "" : split).append((onCooldown(data, skill) - ? onCooldown.replace("{cooldown}", String.valueOf(data.getCooldownMap().getInfo(skill.getSkill()).getRemaining() / 1000)) + ? onCooldown.replace("{cooldown}", String.valueOf(data.getCooldownMap().getInfo(skill).getRemaining() / 1000)) : noMana(data, skill) ? noMana : ready).replace("{index}", "" + (j + 1 + (data.getPlayer().getInventory().getHeldItemSlot() <= j ? 1 : 0))).replace("{skill}", data.getBoundSkill(j).getSkill().getName())); } @@ -138,11 +143,11 @@ public class SpellCast implements Listener { * modifier. We just look for an entry in the cooldown map which * won't be here if the skill has no cooldown. */ - private boolean onCooldown(PlayerData data, SkillInfo skill) { - return data.getCooldownMap().isOnCooldown(skill.getSkill()); + private boolean onCooldown(PlayerData data, ClassSkill skill) { + return data.getCooldownMap().isOnCooldown(skill); } - private boolean noMana(PlayerData data, SkillInfo skill) { + private boolean noMana(PlayerData data, ClassSkill skill) { return skill.getSkill().hasModifier("mana") && skill.getModifier("mana", data.getSkillLevel(skill.getSkill())) > data.getMana(); } diff --git a/src/main/java/net/Indyuce/mmocore/manager/SkillManager.java b/src/main/java/net/Indyuce/mmocore/manager/SkillManager.java index c9d21c57..f3a5f7f6 100644 --- a/src/main/java/net/Indyuce/mmocore/manager/SkillManager.java +++ b/src/main/java/net/Indyuce/mmocore/manager/SkillManager.java @@ -1,128 +1,84 @@ package net.Indyuce.mmocore.manager; +import io.lumine.mythic.lib.MythicLib; +import io.lumine.mythic.lib.skill.handler.SkillHandler; +import net.Indyuce.mmocore.MMOCore; +import net.Indyuce.mmocore.api.ConfigFile; +import net.Indyuce.mmocore.api.util.MMOCoreUtils; +import net.Indyuce.mmocore.skill.RegisteredSkill; + import java.io.File; import java.io.IOException; -import java.lang.reflect.InvocationTargetException; -import java.util.*; -import java.util.jar.JarEntry; -import java.util.jar.JarFile; +import java.io.InputStream; +import java.nio.file.Files; +import java.util.Arrays; +import java.util.Collection; +import java.util.LinkedHashMap; +import java.util.Map; import java.util.logging.Level; -import java.util.stream.Collectors; - -import org.bukkit.Bukkit; -import org.bukkit.configuration.file.YamlConfiguration; - -import net.Indyuce.mmocore.MMOCore; -import net.Indyuce.mmocore.api.ConfigFile; -import net.Indyuce.mmocore.skill.Skill; -import net.Indyuce.mmocore.api.util.math.formula.LinearValue; -import net.Indyuce.mmocore.comp.mythicmobs.MythicSkill; public class SkillManager implements MMOCoreManager { - private final Map skills = new LinkedHashMap<>(); + private final Map skills = new LinkedHashMap<>(); - private boolean hasLoadedDefaultSkills; + public void registerSkill(RegisteredSkill skill) { + skills.put(skill.getHandler().getId().toUpperCase(), skill); + } - public void register(Skill skill) { - skills.put(skill.getId().toUpperCase(), skill); - } + public RegisteredSkill getSkill(String id) { + return skills.get(id.toUpperCase()); + } - public Skill get(String id) { - return skills.get(id.toUpperCase()); - } + public boolean hasSkill(String id) { + return skills.containsKey(id.toUpperCase()); + } - public boolean has(String id) { - return skills.containsKey(id.toUpperCase()); - } + public Collection getAll() { + return skills.values(); + } - public Collection getAll() { - return skills.values(); - } + public void initialize(boolean clearBefore) { - public Set getActive() { - return skills.values().stream().filter(skill -> !skill.isPassive()).collect(Collectors.toSet()); - } + if (clearBefore) + skills.clear(); - public Set getKeys() { - return skills.keySet(); - } + File skillsFolder = new File(MMOCore.plugin.getDataFolder() + "/skills"); + if (!skillsFolder.exists()) + skillsFolder.mkdir(); - @Override - public void initialize(boolean clearBefore) { + // Check for default files + File skillFolder = new File(MMOCore.plugin.getDataFolder() + "/skills"); + if (!skillFolder.exists()) + try { + skillFolder.mkdir(); - if (clearBefore) { + for (SkillHandler handler : MythicLib.plugin.getSkills().getHandlers()) { + InputStream res = MMOCore.plugin.getResource("default/skills/" + handler.getLowerCaseId() + ".yml"); + if (res != null) + Files.copy(res, new File(MMOCore.plugin.getDataFolder() + "/skills/" + handler.getLowerCaseId() + ".yml").getAbsoluteFile().toPath()); + } + } catch (IOException exception) { + MMOCore.plugin.getLogger().log(Level.WARNING, "Could not save default skill configs: " + exception.getMessage()); + } - // Only remove custom skills - Iterator ite = skills.values().iterator(); - while (ite.hasNext()) { - Skill next = ite.next(); - if (next instanceof MythicSkill) - ite.remove(); - } - } + for (SkillHandler handler : MythicLib.plugin.getSkills().getHandlers()) { - if (!hasLoadedDefaultSkills) - try { - hasLoadedDefaultSkills = true; - JarFile jarFile = new JarFile(MMOCore.plugin.getJarFile()); - JarEntry entry; - for (Enumeration en = jarFile.entries(); en.hasMoreElements();) - if ((entry = en.nextElement()).getName().startsWith("net/Indyuce/mmocore/skill/list/") - && !entry.isDirectory() && !entry.getName().contains("$")) - register((Skill) Class.forName(entry.getName().replace("/", ".").replace(".class", "")).getDeclaredConstructor().newInstance()); - jarFile.close(); - } catch (IOException | InstantiationException | IllegalAccessException | ClassNotFoundException | NoSuchMethodException | InvocationTargetException exception) { - exception.printStackTrace(); - MMOCore.log(Level.WARNING, "Could not load skills! Careful with player data :("); - } + // Check if config file exists + ConfigFile config = new ConfigFile("/skills", handler.getLowerCaseId()); + if (!config.exists()) { + config.getConfig().set("name", MMOCoreUtils.caseOnWords(handler.getId().replace("_", " ").replace("-", " ").toLowerCase())); + config.getConfig().set("lore", Arrays.asList("This is the default skill description", "", "&e{cooldown}s Cooldown", "&9Costs {mana} {mana_name}")); + config.getConfig().set("material", "BOOK"); + for (Object mod : handler.getModifiers()) { + config.getConfig().set(mod + ".base", 0); + config.getConfig().set(mod + ".per-level", 0); + config.getConfig().set(mod + ".min", 0); + config.getConfig().set(mod + ".max", 0); + } + config.save(); + } - if (!new File(MMOCore.plugin.getDataFolder() + "/skills").exists()) - new File(MMOCore.plugin.getDataFolder() + "/skills").mkdir(); - - File mythicMobs = new File(MMOCore.plugin.getDataFolder() + "/skills/mythic-mobs"); - if (!mythicMobs.exists()) - mythicMobs.mkdir(); - - // Load MythicMobs addon skills - if (Bukkit.getPluginManager().getPlugin("MythicMobs") != null) - for (File file : mythicMobs.listFiles()) { - try { - register(new MythicSkill(file.getName().substring(0, file.getName().length() - 4).toUpperCase(), - YamlConfiguration.loadConfiguration(file))); - } catch (Exception exception) { - MMOCore.plugin.getLogger().log(Level.WARNING, "Could not load skill from " + file.getName() + ": " + exception.getMessage()); - } - } - - // Load configuration for default skills - for (Skill skill : getAll()) - if (!(skill instanceof MythicSkill)) { - File file = new File(MMOCore.plugin.getDataFolder() + "/skills", skill.getLowerCaseId() + ".yml"); - ConfigFile config = new ConfigFile("/skills", skill.getLowerCaseId()); - - if (!file.exists()) { - config.getConfig().set("name", skill.getName()); - config.getConfig().set("lore", skill.getLore()); - - /* - * It does support custom modeled items but it does not - * provide default configs for that. - */ - config.getConfig().set("material", skill.getIcon().getType().name()); - - for (String mod : skill.getModifiers()) { - LinearValue value = skill.getModifierInfo(mod); - config.getConfig().set(mod + ".base", value.getBaseValue()); - config.getConfig().set(mod + ".per-level", value.getPerLevel()); - if (value.hasMax()) - config.getConfig().set(mod + ".max", value.getMax()); - if (value.hasMin()) - config.getConfig().set(mod + ".min", value.getMin()); - } - config.save(); - } - - skill.update(config.getConfig()); - } - } + RegisteredSkill skill = new RegisteredSkill(handler, config.getConfig()); + this.skills.put(handler.getId(), skill); + } + } } diff --git a/src/main/java/net/Indyuce/mmocore/manager/data/mysql/MySQLPlayerDataManager.java b/src/main/java/net/Indyuce/mmocore/manager/data/mysql/MySQLPlayerDataManager.java index b9cefc77..e7702a02 100644 --- a/src/main/java/net/Indyuce/mmocore/manager/data/mysql/MySQLPlayerDataManager.java +++ b/src/main/java/net/Indyuce/mmocore/manager/data/mysql/MySQLPlayerDataManager.java @@ -135,7 +135,7 @@ public class MySQLPlayerDataManager extends PlayerDataManager { sql.updateJSONArray("waypoints", data.getWaypoints()); sql.updateJSONArray("friends", data.getFriends().stream().map(UUID::toString).collect(Collectors.toList())); - sql.updateJSONArray("bound_skills", data.getBoundSkills().stream().map(skill -> skill.getSkill().getId()).collect(Collectors.toList())); + sql.updateJSONArray("bound_skills", data.getBoundSkills().stream().map(skill -> skill.getSkill().getHandler().getId()).collect(Collectors.toList())); sql.updateJSONObject("skills", data.mapSkillLevels().entrySet()); diff --git a/src/main/java/net/Indyuce/mmocore/manager/data/yaml/YAMLPlayerDataManager.java b/src/main/java/net/Indyuce/mmocore/manager/data/yaml/YAMLPlayerDataManager.java index 48033be2..92b927c8 100644 --- a/src/main/java/net/Indyuce/mmocore/manager/data/yaml/YAMLPlayerDataManager.java +++ b/src/main/java/net/Indyuce/mmocore/manager/data/yaml/YAMLPlayerDataManager.java @@ -95,7 +95,7 @@ public class YAMLPlayerDataManager extends PlayerDataManager { data.mapSkillLevels().forEach((key1, value) -> config.set("skill." + key1, value)); List boundSkills = new ArrayList<>(); - data.getBoundSkills().forEach(skill -> boundSkills.add(skill.getSkill().getId())); + data.getBoundSkills().forEach(skill -> boundSkills.add(skill.getSkill().getHandler().getId())); config.set("bound-skills", boundSkills); config.set("attribute", null); diff --git a/src/main/java/net/Indyuce/mmocore/skill/CastableSkill.java b/src/main/java/net/Indyuce/mmocore/skill/CastableSkill.java new file mode 100644 index 00000000..257b67bf --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/skill/CastableSkill.java @@ -0,0 +1,87 @@ +package net.Indyuce.mmocore.skill; + +import io.lumine.mythic.lib.MythicLib; +import io.lumine.mythic.lib.comp.flags.CustomFlag; +import io.lumine.mythic.lib.player.cooldown.CooldownInfo; +import io.lumine.mythic.lib.skill.Skill; +import io.lumine.mythic.lib.skill.SkillMetadata; +import io.lumine.mythic.lib.skill.handler.SkillHandler; +import net.Indyuce.mmocore.MMOCore; +import net.Indyuce.mmocore.api.event.PlayerResourceUpdateEvent; +import net.Indyuce.mmocore.api.player.PlayerData; + +public class CastableSkill extends Skill { + private final ClassSkill skill; + private final int skillLevel; + + public CastableSkill(ClassSkill skill, int skillLevel) { + this.skill = skill; + this.skillLevel = skillLevel; + } + + public ClassSkill getSkill() { + return skill; + } + + @Override + public boolean getResult(SkillMetadata skillMeta) { + PlayerData playerData = PlayerData.get(skillMeta.getCaster().getData().getUniqueId()); + + // If the caster has unlocked that skill + if (!playerData.hasSkillUnlocked(skill)) { + MMOCore.plugin.configManager.getSimpleMessage("not-unlocked-skill").send(playerData.getPlayer()); + return false; + } + + // Cooldown check + if (!skillMeta.getCaster().getData().getCooldownMap().isOnCooldown(this)) { + MMOCore.plugin.configManager.getSimpleMessage("casting.on-cooldown").send(playerData.getPlayer()); + return false; + } + + // Mana cost + if (playerData.getMana() < getModifier("mana")) { + MMOCore.plugin.configManager.getSimpleMessage("casting.no-mana", "mana", playerData.getProfess().getManaDisplay().getName()).send(playerData.getPlayer()); + return false; + } + + // Stamina cost + if (playerData.getStamina() < getModifier("stamina")) { + MMOCore.plugin.configManager.getSimpleMessage("casting.no-stamina").send(playerData.getPlayer()); + return false; + } + + // Ability flag + if (!MythicLib.plugin.getFlags().isFlagAllowed(skillMeta.getCaster().getPlayer(), CustomFlag.MMO_ABILITIES)) + return false; + + return true; + } + + @Override + public void whenCast(SkillMetadata skillMeta) { + PlayerData casterData = PlayerData.get(skillMeta.getCaster().getData().getUniqueId()); + + // Apply cooldown, mana and stamina costs + if (!casterData.noCooldown) { + + // Cooldown + double flatCooldownReduction = Math.max(0, Math.min(1, skillMeta.getCaster().getStat("COOLDOWN_REDUCTION") / 100)); + CooldownInfo cooldownHandler = skillMeta.getCaster().getData().getCooldownMap().applyCooldown(this, getModifier("cooldown")); + cooldownHandler.reduceInitialCooldown(flatCooldownReduction); + + casterData.giveMana(-getModifier("mana"), PlayerResourceUpdateEvent.UpdateReason.SKILL_COST); + casterData.giveStamina(-getModifier("stamina"), PlayerResourceUpdateEvent.UpdateReason.SKILL_COST); + } + } + + @Override + public SkillHandler getHandler() { + return skill.getSkill().getHandler(); + } + + @Override + public double getModifier(String mod) { + return skill.getModifier(mod, skillLevel); + } +} diff --git a/src/main/java/net/Indyuce/mmocore/skill/CasterMetadata.java b/src/main/java/net/Indyuce/mmocore/skill/CasterMetadata.java deleted file mode 100644 index 573a092b..00000000 --- a/src/main/java/net/Indyuce/mmocore/skill/CasterMetadata.java +++ /dev/null @@ -1,57 +0,0 @@ -package net.Indyuce.mmocore.skill; - -import io.lumine.mythic.lib.MythicLib; -import io.lumine.mythic.lib.api.player.EquipmentSlot; -import io.lumine.mythic.lib.api.stat.StatMap; -import io.lumine.mythic.lib.damage.AttackMetadata; -import io.lumine.mythic.lib.damage.DamageMetadata; -import io.lumine.mythic.lib.damage.DamageType; -import net.Indyuce.mmocore.api.player.PlayerData; -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Player; - -public class CasterMetadata { - private final Player player; - private final PlayerData caster; - private final StatMap.CachedStatMap stats; - - /** - * Instantiated every time a player casts a skill. This is - * used to temporarily cache the player's statistics - * - * @param caster Player casting the skill - */ - public CasterMetadata(PlayerData caster) { - this.player = caster.getPlayer(); - this.caster = caster; - this.stats = caster.getMMOPlayerData().getStatMap().cache(EquipmentSlot.MAIN_HAND); - } - - public Player getPlayer() { - return player; - } - - public PlayerData getPlayerData() { - return caster; - } - - public StatMap.CachedStatMap getStats() { - return stats; - } - - /** - * Utility method that makes a player deal damage to a specific - * entity. This creates the attackMetadata based on the data - * stored by the CasterMetadata, and calls it using MythicLib - * damage manager - * - * @param target Target entity - * @param damage Damage dealt - * @param types Type of target - * @return - */ - public void attack(LivingEntity target, double damage, DamageType... types) { - AttackMetadata attackMeta = new AttackMetadata(new DamageMetadata(damage, types), stats); - MythicLib.plugin.getDamage().damage(attackMeta, target); - } -} diff --git a/src/main/java/net/Indyuce/mmocore/skill/ClassSkill.java b/src/main/java/net/Indyuce/mmocore/skill/ClassSkill.java new file mode 100644 index 00000000..44f02353 --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/skill/ClassSkill.java @@ -0,0 +1,123 @@ +package net.Indyuce.mmocore.skill; + +import io.lumine.mythic.lib.api.player.EquipmentSlot; +import io.lumine.mythic.lib.api.stat.modifier.ModifierSource; +import io.lumine.mythic.lib.player.cooldown.CooldownObject; +import io.lumine.mythic.lib.skill.trigger.PassiveSkill; +import net.Indyuce.mmocore.api.player.PlayerData; +import net.Indyuce.mmocore.api.util.math.formula.IntegerLinearValue; +import net.Indyuce.mmocore.api.util.math.formula.LinearValue; +import org.apache.commons.lang.Validate; +import org.bukkit.configuration.ConfigurationSection; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class ClassSkill implements CooldownObject { + private final RegisteredSkill skill; + private final int unlockLevel, maxSkillLevel; + private final Map modifiers = new HashMap<>(); + + public ClassSkill(RegisteredSkill skill, int unlockLevel) { + this(skill, unlockLevel, 0); + } + + /** + * Class used to save information about skills IN A CLASS CONTEXT i.e at + * which level the skill can be unlocked, etc. + */ + public ClassSkill(RegisteredSkill skill, int unlockLevel, int maxSkillLevel) { + this.skill = skill; + this.unlockLevel = unlockLevel; + this.maxSkillLevel = maxSkillLevel; + + for (String mod : skill.getHandler().getModifiers()) + this.modifiers.put(mod, skill.getModifierInfo(mod)); + } + + public ClassSkill(RegisteredSkill skill, ConfigurationSection config) { + this.skill = skill; + unlockLevel = config.getInt("level"); + maxSkillLevel = config.getInt("max-level"); + + for (String mod : skill.getHandler().getModifiers()) { + LinearValue defaultValue = skill.getModifierInfo(mod); + this.modifiers.put(mod, config.isConfigurationSection(mod) ? readLinearValue(defaultValue, config.getConfigurationSection(mod)) : defaultValue); + } + } + + public RegisteredSkill getSkill() { + return skill; + } + + public int getUnlockLevel() { + return unlockLevel; + } + + public boolean hasMaxLevel() { + return maxSkillLevel > 0; + } + + public int getMaxLevel() { + return maxSkillLevel; + } + + /* + * this method can only OVERRIDE default modifiers + */ + public void addModifier(String modifier, LinearValue linear) { + if (modifiers.containsKey(modifier)) + modifiers.put(modifier, linear); + } + + public double getModifier(String modifier, int level) { + return modifiers.get(modifier).calculate(level); + } + + public List calculateLore(PlayerData data) { + return calculateLore(data, data.getSkillLevel(skill)); + } + + public List calculateLore(PlayerData data, int x) { + List list = new ArrayList<>(); + + Map placeholders = calculateModifiers(x); + placeholders.put("mana_name", data.getProfess().getManaDisplay().getName()); + skill.getLore().forEach(str -> list.add(applyPlaceholders(placeholders, str))); + + return list; + } + + private String applyPlaceholders(Map placeholders, String str) { + while (str.contains("{") && str.substring(str.indexOf("{")).contains("}")) { + String holder = str.substring(str.indexOf("{") + 1, str.indexOf("}")); + str = str.replace("{" + holder + "}", placeholders.getOrDefault(holder, "PHE")); + } + return str; + } + + private Map calculateModifiers(int x) { + Map map = new HashMap<>(); + modifiers.keySet().forEach(modifier -> map.put(modifier, modifiers.get(modifier).getDisplay(x))); + return map; + } + + private LinearValue readLinearValue(LinearValue current, ConfigurationSection config) { + return current instanceof IntegerLinearValue ? new IntegerLinearValue(config) : new LinearValue(config); + } + + public CastableSkill toCastable(PlayerData caster) { + return new CastableSkill(this, caster.getSkillLevel(getSkill())); + } + + public PassiveSkill toPassive(PlayerData caster) { + Validate.isTrue(skill.hasTrigger(), "Skill is active"); + return new PassiveSkill("MMOCorePassiveSkill", skill.getTrigger(), toCastable(caster), EquipmentSlot.OTHER, ModifierSource.OTHER); + } + + public String getCooldownPath() { + return "skill_" + skill.getHandler().getId(); + } +} \ No newline at end of file diff --git a/src/main/java/net/Indyuce/mmocore/skill/PassiveSkill.java b/src/main/java/net/Indyuce/mmocore/skill/PassiveSkill.java deleted file mode 100644 index acb7894b..00000000 --- a/src/main/java/net/Indyuce/mmocore/skill/PassiveSkill.java +++ /dev/null @@ -1,19 +0,0 @@ -package net.Indyuce.mmocore.skill; - -import net.Indyuce.mmocore.skill.metadata.SkillMetadata; -import org.bukkit.event.Listener; - -public class PassiveSkill extends Skill implements Listener { - public PassiveSkill() { - super(); - } - - public PassiveSkill(String id) { - super(id); - } - - @Override - public SkillMetadata whenCast(CasterMetadata casterMeta, SkillInfo skill) { - return new SkillMetadata(casterMeta, skill); - } -} diff --git a/src/main/java/net/Indyuce/mmocore/skill/PlayerSkillData.java b/src/main/java/net/Indyuce/mmocore/skill/PlayerSkillData.java deleted file mode 100644 index ced80f33..00000000 --- a/src/main/java/net/Indyuce/mmocore/skill/PlayerSkillData.java +++ /dev/null @@ -1,75 +0,0 @@ -package net.Indyuce.mmocore.skill; - -import java.util.HashMap; -import java.util.Map; - -import net.Indyuce.mmocore.api.player.PlayerData; -import net.Indyuce.mmocore.skill.Skill.SkillInfo; - -/** - * Note: any method which return longs returns milliseconds. - * - * @author cympe - */ -public class PlayerSkillData { - private final Map cooldowns = new HashMap<>(); - private final PlayerData data; - - public PlayerSkillData(PlayerData data) { - this.data = data; - } - - public long getCooldown(SkillInfo skill) { - return Math.max(0, lastCast(skill.getSkill()) - System.currentTimeMillis() - + (long) (1000. * skill.getModifier("cooldown", data.getSkillLevel(skill.getSkill())))); - } - - /** - * @param skill - * Skill that was cast - * @return Last time stamp the skill was cast or 0 if never - */ - public long lastCast(Skill skill) { - return cooldowns.containsKey(skill.getId()) ? cooldowns.get(skill.getId()) : 0; - } - - /** - * Sets the last time the player cast the skill at current time - * - * @param skill - * Skill being cast - */ - public void setLastCast(Skill skill) { - setLastCast(skill, System.currentTimeMillis()); - } - - /** - * Sets the last time the player cast the skill at given time - * - * @param ms - * Time stammp - * @param skill - * Skill being cast - */ - public void setLastCast(Skill skill, long ms) { - cooldowns.put(skill.getId(), ms); - } - - /** - * Reduces the remaining cooldown of a specific skill - * - * @param skill - * Skill cast - * @param value - * Amount of skill cooldown instant reduction. - * @param relative - * If the cooldown reduction is relative to the remaining - * cooldown. If set to true, instant reduction is equal to - * (value) * (skill cooldown). If set to false, instant reduction - * is the given flat value - */ - public void reduceCooldown(SkillInfo skill, double value, boolean relative) { - long reduction = (long) (relative ? value * (double) getCooldown(skill) : value * 1000.); - cooldowns.put(skill.getSkill().getId(), lastCast(skill.getSkill()) + reduction); - } -} diff --git a/src/main/java/net/Indyuce/mmocore/skill/RegisteredSkill.java b/src/main/java/net/Indyuce/mmocore/skill/RegisteredSkill.java new file mode 100644 index 00000000..fc17ba66 --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/skill/RegisteredSkill.java @@ -0,0 +1,121 @@ +package net.Indyuce.mmocore.skill; + +import io.lumine.mythic.lib.skill.handler.SkillHandler; +import io.lumine.mythic.lib.skill.trigger.TriggerType; +import net.Indyuce.mmocore.api.util.MMOCoreUtils; +import net.Indyuce.mmocore.api.util.math.formula.LinearValue; +import org.apache.commons.lang.Validate; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +public class RegisteredSkill { + private final SkillHandler handler; + + private final String name; + private final Map defaultModifiers = new HashMap<>(); + private final ItemStack icon; + private final List lore; + private final TriggerType triggerType; + + public RegisteredSkill(SkillHandler handler, ConfigurationSection config) { + this.handler = handler; + + name = Objects.requireNonNull(config.getString("name"), "Could not find skill name"); + icon = MMOCoreUtils.readIcon(Objects.requireNonNull(config.getString("material"), "Could not find skill icon")); + lore = Objects.requireNonNull(config.getStringList("lore"), "Could not find skill lore"); + + // Trigger type + Validate.isTrue(getHandler().isTriggerable() || !config.contains("passive-type"), "Cannot change the trigger type of a default passive skill"); + triggerType = config.contains("passive-type") ? TriggerType.valueOf(config.getString("passive-type").toUpperCase().replace(" ", "_").replace("-", "_")) : null; + + for (String mod : handler.getModifiers()) + defaultModifiers.put(mod, config.contains(mod) ? new LinearValue(config.getConfigurationSection(mod)) : LinearValue.ZERO); + } + + public RegisteredSkill(SkillHandler handler, String name, ItemStack icon, List lore, @Nullable TriggerType triggerType) { + this.handler = handler; + this.name = name; + this.icon = icon; + this.lore = lore; + this.triggerType = triggerType; + } + + public SkillHandler getHandler() { + return handler; + } + + public String getName() { + return name; + } + + public List getLore() { + return lore; + } + + public ItemStack getIcon() { + return icon.clone(); + } + + public boolean hasModifier(String modifier) { + return defaultModifiers.containsKey(modifier); + } + + /** + * There are three types of MMOCore skills: + * - skills with no trigger type (therefore active) + * - default passive skills with no trigger type + * - custom skills with a trigger type (therefore passive) + *

+ * Illegal: + * - default passive skills with a trigger type + * + * @return If the skill should + */ + public boolean hasTrigger() { + return triggerType != null; + } + + /** + * Two types of passive skills: + * - custom passive skills, with a trigger type + * - default passive skills which are untriggerable + *

+ * This option dictates whether or not it + * can be cast when in casting mode. + * + * @return If the given skill is passive + */ + public boolean isPassive() { + return triggerType != null || !getHandler().isTriggerable(); + } + + @NotNull + public TriggerType getTrigger() { + return Objects.requireNonNull(triggerType, "Skill has no trigger"); + } + + public void addModifier(String modifier, LinearValue linear) { + defaultModifiers.put(modifier, linear); + } + + @Deprecated + public void addModifierIfNone(String mod, LinearValue defaultValue) { + if (!hasModifier(mod)) + addModifier(mod, defaultValue); + } + + public LinearValue getModifierInfo(String modifier) { + return defaultModifiers.get(modifier); + } + + public double getModifier(String modifier, int level) { + return defaultModifiers.get(modifier).calculate(level); + } +} diff --git a/src/main/java/net/Indyuce/mmocore/skill/Skill.java b/src/main/java/net/Indyuce/mmocore/skill/Skill.java deleted file mode 100644 index 68889ee4..00000000 --- a/src/main/java/net/Indyuce/mmocore/skill/Skill.java +++ /dev/null @@ -1,231 +0,0 @@ -package net.Indyuce.mmocore.skill; - -import io.lumine.mythic.lib.player.cooldown.CooldownObject; -import net.Indyuce.mmocore.api.player.PlayerData; -import net.Indyuce.mmocore.api.util.MMOCoreUtils; -import net.Indyuce.mmocore.api.util.math.formula.IntegerLinearValue; -import net.Indyuce.mmocore.api.util.math.formula.LinearValue; -import net.Indyuce.mmocore.skill.metadata.SkillMetadata; -import org.apache.commons.lang.Validate; -import org.bukkit.Material; -import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.inventory.ItemStack; - -import java.util.*; - -public abstract class Skill implements CooldownObject { - private final String id; - - private String name; - private ItemStack icon = new ItemStack(Material.BOOK); - private List lore; - private boolean passive; - - private final Map modifiers = new HashMap<>(); - private final Skill skill = this; - - protected static final Random random = new Random(); - - public Skill() { - id = getClass().getSimpleName().toUpperCase(); - name = getClass().getSimpleName().replace("_", " "); - - Validate.notNull(id, "ID cannot be null"); - Validate.notNull(id, "Name cannot be null"); - - // Default modifiers - addModifierIfNone("mana", LinearValue.ZERO); - addModifierIfNone("stamina", LinearValue.ZERO); - } - - public Skill(String id) { - this.id = id.toUpperCase().replace(" ", "_").replace("-", "_"); - } - - public void setName(String name) { - this.name = name; - } - - public void setMaterial(Material material) { - setIcon(new ItemStack(material)); - } - - public void setIcon(ItemStack item) { - this.icon = item; - } - - public void setLore(String... lore) { - setLore(Arrays.asList(lore)); - } - - public void setLore(List lore) { - this.lore = lore; - } - - public void setPassive() { - passive = true; - } - - public String getName() { - return name; - } - - public String getId() { - return id; - } - - public String getLowerCaseId() { - return id.replace("_", "-").toLowerCase(); - } - - public List getLore() { - return lore; - } - - public ItemStack getIcon() { - return icon.clone(); - } - - @Override - public String getCooldownPath() { - return "mmocore_skill_" + id.toLowerCase(); - } - - /** - * Passive skills do not display any message when trying to cast them - * - * @return If the skill is passive - */ - public boolean isPassive() { - return passive; - } - - public boolean hasModifier(String modifier) { - return modifiers.containsKey(modifier); - } - - public void addModifier(String modifier, LinearValue linear) { - modifiers.put(modifier, linear); - } - - public void addModifierIfNone(String mod, LinearValue defaultValue) { - if (!hasModifier(mod)) - addModifier(mod, defaultValue); - } - - public LinearValue getModifierInfo(String modifier) { - return modifiers.get(modifier); - } - - public double getModifier(String modifier, int level) { - return modifiers.get(modifier).calculate(level); - } - - public Set getModifiers() { - return modifiers.keySet(); - } - - public void update(FileConfiguration config) { - name = config.getString("name", "INVALID NAME"); - lore = config.getStringList("lore"); - icon = MMOCoreUtils.readIcon(config.getString("material", "DIRT")); - - for (String modifier : modifiers.keySet()) - if (config.contains(modifier)) - modifiers.put(modifier, readLinearValue(modifiers.get(modifier), config.getConfigurationSection(modifier))); - } - - private LinearValue readLinearValue(LinearValue current, ConfigurationSection config) { - return current instanceof IntegerLinearValue ? new IntegerLinearValue(config) : new LinearValue(config); - } - - public abstract SkillMetadata whenCast(CasterMetadata casterMeta, SkillInfo skill); - - public SkillInfo newSkillInfo(ConfigurationSection config) { - return new SkillInfo(config); - } - - public SkillInfo newSkillInfo(int level) { - return new SkillInfo(level); - } - - public class SkillInfo { - private final int level, max; - private final Map modifiers = new HashMap<>(skill.modifiers); - - /* - * class used to save information about skills IN A CLASS CONTEXT i.e at - * which level the skill can be unlocked, etc. - */ - public SkillInfo(int level) { - this.level = level; - this.max = 0; - } - - public SkillInfo(ConfigurationSection config) { - level = config.getInt("level"); - max = config.getInt("max-level"); - - for (String key : config.getKeys(false)) - if (config.get(key) instanceof ConfigurationSection && modifiers.containsKey(key)) - modifiers.put(key, readLinearValue(modifiers.get(key), config.getConfigurationSection(key))); - } - - public Skill getSkill() { - return skill; - } - - public int getUnlockLevel() { - return level; - } - - public boolean hasMaxLevel() { - return max > 0; - } - - public int getMaxLevel() { - return max; - } - - /* - * this method can only OVERRIDE default modifiers - */ - public void addModifier(String modifier, LinearValue linear) { - if (modifiers.containsKey(modifier)) - modifiers.put(modifier, linear); - } - - public double getModifier(String modifier, int level) { - return modifiers.get(modifier).calculate(level); - } - - public List calculateLore(PlayerData data) { - return calculateLore(data, data.getSkillLevel(skill)); - } - - public List calculateLore(PlayerData data, int x) { - List list = new ArrayList<>(); - - Map placeholders = calculateModifiers(x); - placeholders.put("mana_name", data.getProfess().getManaDisplay().getName()); - lore.forEach(str -> list.add(applyPlaceholders(placeholders, str))); - - return list; - } - - private String applyPlaceholders(Map placeholders, String str) { - while (str.contains("{") && str.substring(str.indexOf("{")).contains("}")) { - String holder = str.substring(str.indexOf("{") + 1, str.indexOf("}")); - str = str.replace("{" + holder + "}", placeholders.getOrDefault(holder, "PHE")); - } - return str; - } - - private Map calculateModifiers(int x) { - Map map = new HashMap<>(); - modifiers.keySet().forEach(modifier -> map.put(modifier, modifiers.get(modifier).getDisplay(x))); - return map; - } - } -} diff --git a/src/main/java/net/Indyuce/mmocore/skill/list/Ambers.java b/src/main/java/net/Indyuce/mmocore/skill/list/Ambers.java index dcc8dd75..b3629fd7 100644 --- a/src/main/java/net/Indyuce/mmocore/skill/list/Ambers.java +++ b/src/main/java/net/Indyuce/mmocore/skill/list/Ambers.java @@ -1,71 +1,80 @@ package net.Indyuce.mmocore.skill.list; +import io.lumine.mythic.lib.MythicLib; import io.lumine.mythic.lib.api.event.PlayerAttackEvent; +import io.lumine.mythic.lib.api.player.MMOPlayerData; import io.lumine.mythic.lib.damage.DamageType; -import net.Indyuce.mmocore.MMOCore; +import io.lumine.mythic.lib.skill.SkillMetadata; +import io.lumine.mythic.lib.skill.handler.SkillHandler; +import io.lumine.mythic.lib.skill.result.def.SimpleSkillResult; +import io.lumine.mythic.lib.skill.trigger.PassiveSkill; +import io.lumine.mythic.lib.skill.trigger.TriggerMetadata; +import io.lumine.mythic.lib.util.EntityLocationType; +import io.lumine.mythic.lib.util.ParabolicProjectile; import net.Indyuce.mmocore.api.event.PlayerResourceUpdateEvent; import net.Indyuce.mmocore.api.player.PlayerData; -import net.Indyuce.mmocore.api.player.stats.StatType; -import net.Indyuce.mmocore.api.util.math.formula.LinearValue; -import net.Indyuce.mmocore.api.util.math.particle.ParabolicProjectile; -import net.Indyuce.mmocore.skill.PassiveSkill; -import net.Indyuce.mmocore.skill.metadata.SkillMetadata; -import org.bukkit.*; +import org.bukkit.Color; +import org.bukkit.Location; +import org.bukkit.Particle; +import org.bukkit.Sound; +import org.bukkit.entity.LivingEntity; import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; import org.bukkit.scheduler.BukkitRunnable; -public class Ambers extends PassiveSkill { +public class Ambers extends SkillHandler implements Listener { public Ambers() { - super(); + super(false); - setMaterial(Material.EMERALD); - setLore("Dealing magic damage has &630% &7chance", "of dropping an amber on the ground.", "", "When picked up, ambers stack and", - "refund &9{percent}% &7of your missing mana.", "", "&oAmbers can be used in other damaging skills.", - "&oThe more you collect, the more powerful the skills.", "", "&e{cooldown}s Cooldown"); - setPassive(); + registerModifiers("percent"); + } - addModifier("cooldown", new LinearValue(3, -.1, 1, 3)); - addModifier("percent", new LinearValue(10, .1, 10, 20)); + @Override + public SimpleSkillResult getResult(SkillMetadata meta) { + return new SimpleSkillResult(meta.hasAttackBound() && meta.hasTargetEntity() && meta.getTargetEntityOrNull() instanceof LivingEntity); + } - Bukkit.getPluginManager().registerEvents(this, MMOCore.plugin); + @Override + public void whenCast(SimpleSkillResult result, SkillMetadata skillMeta) { + LivingEntity target = (LivingEntity) skillMeta.getTargetEntityOrNull(); + Location loc = target.getLocation(); + + double a = random.nextDouble() * 2 * Math.PI; + new Amber(skillMeta.getCaster().getData(), EntityLocationType.BODY.getLocation(target), loc.clone().add(4 * Math.cos(a), 0, 4 * Math.sin(a)), skillMeta.getModifier("percent")); } @EventHandler - public void a(PlayerAttackEvent event) { - PlayerData data = PlayerData.get(event.getData().getUniqueId()); - if (!event.getAttack().getDamage().hasType(DamageType.SKILL) || !data.getProfess().hasSkill(this)) + public void spawnAmber(PlayerAttackEvent event) { + MMOPlayerData data = event.getData(); + if (!event.getAttack().getDamage().hasType(DamageType.SKILL)) return; - SkillMetadata cast = data.cast(this); - if (!cast.isSuccessful()) + PassiveSkill passive = data.getPassiveSkill(this); + if (passive == null) return; - Location loc = event.getEntity().getLocation(); - double a = random.nextDouble() * 2 * Math.PI; - - new Amber(data, loc.add(0, event.getEntity().getHeight() / 2, 0), loc.clone().add(4 * Math.cos(a), 0, 4 * Math.sin(a)), cast.getModifier("percent")); + passive.getTriggeredSkill().cast(new TriggerMetadata(event.getAttack(), event.getEntity())); } public static class Amber extends BukkitRunnable { private final Location loc; - private final PlayerData data; + private final MMOPlayerData data; private final double percent; private int j; - private Amber(PlayerData data, Location source, Location loc, double percent) { + private Amber(MMOPlayerData data, Location source, Location loc, double percent) { this.loc = loc; this.data = data; this.percent = percent / 100; final Amber amber = this; - new ParabolicProjectile(source, loc, Particle.REDSTONE, () -> amber.runTaskTimer(MMOCore.plugin, 0, 3), 1, Color.ORANGE, 1.3f); + new ParabolicProjectile(source, loc, Particle.REDSTONE, () -> amber.runTaskTimer(MythicLib.plugin, 0, 3), 1, Color.ORANGE, 1.3f); } @Override public void run() { - if (!data.isOnline()) return; - if (j++ > 66 || !data.getPlayer().getWorld().equals(loc.getWorld())) { + if (j++ > 66 || !data.isOnline() || !data.getPlayer().getWorld().equals(loc.getWorld())) { cancel(); return; } @@ -74,7 +83,11 @@ public class Ambers extends PassiveSkill { data.getPlayer().playSound(data.getPlayer().getLocation(), Sound.BLOCK_END_PORTAL_FRAME_FILL, 1, 1); // data.getSkillData().ambers++; - data.giveMana((data.getStats().getStat(StatType.MAX_MANA) - data.getMana()) * percent, PlayerResourceUpdateEvent.UpdateReason.SKILL_REGENERATION); + + // Give mana back + PlayerData playerData = PlayerData.get(data.getUniqueId()); + double missingMana = data.getStatMap().getStat("MAX_MANA") - playerData.getMana(); + playerData.giveMana(missingMana * percent, PlayerResourceUpdateEvent.UpdateReason.SKILL_REGENERATION); cancel(); return; diff --git a/src/main/java/net/Indyuce/mmocore/skill/list/Backstab.java b/src/main/java/net/Indyuce/mmocore/skill/list/Backstab.java deleted file mode 100644 index 6bfc7dba..00000000 --- a/src/main/java/net/Indyuce/mmocore/skill/list/Backstab.java +++ /dev/null @@ -1,50 +0,0 @@ -package net.Indyuce.mmocore.skill.list; - -import io.lumine.mythic.lib.api.event.PlayerAttackEvent; -import io.lumine.mythic.lib.damage.DamageType; -import net.Indyuce.mmocore.MMOCore; -import net.Indyuce.mmocore.api.player.PlayerData; -import net.Indyuce.mmocore.api.util.math.formula.LinearValue; -import net.Indyuce.mmocore.skill.PassiveSkill; -import net.Indyuce.mmocore.skill.metadata.SkillMetadata; -import org.bukkit.Bukkit; -import org.bukkit.Material; -import org.bukkit.Particle; -import org.bukkit.Sound; -import org.bukkit.entity.LivingEntity; -import org.bukkit.event.EventHandler; - -public class Backstab extends PassiveSkill { - public Backstab() { - super(); - - setMaterial(Material.FLINT); - setLore("Backstabs deal &c{extra}%&7 damage.", "", "&9Costs {mana} {mana_name}"); - setPassive(); - - addModifier("cooldown", new LinearValue(0, 0)); - addModifier("mana", new LinearValue(8, 1)); - addModifier("extra", new LinearValue(50, 20)); - - Bukkit.getPluginManager().registerEvents(this, MMOCore.plugin); - } - - @EventHandler - public void a(PlayerAttackEvent event) { - PlayerData data = PlayerData.get(event.getData().getUniqueId()); - LivingEntity target = event.getEntity(); - if (!event.getAttack().getDamage().hasType(DamageType.WEAPON) - || event.getPlayer().getEyeLocation().getDirection().angle(target.getEyeLocation().getDirection()) > Math.PI / 6 - || !data.getProfess().hasSkill(this)) - return; - - SkillMetadata cast = data.cast(this); - if (!cast.isSuccessful()) - return; - - data.cast(cast.getInfo()); - event.getAttack().getDamage().multiply(1 + cast.getModifier("extra") / 100, DamageType.PHYSICAL); - target.getWorld().spawnParticle(Particle.CRIT, target.getLocation().add(0, target.getHeight() / 2, 0), 32, 0, 0, 0, .05); - target.getWorld().playSound(target.getLocation(), Sound.ENTITY_ENDERMAN_HURT, 1, 1.5f); - } -} diff --git a/src/main/java/net/Indyuce/mmocore/skill/list/Combo_Attack.java b/src/main/java/net/Indyuce/mmocore/skill/list/Combo_Attack.java deleted file mode 100644 index e9f363c1..00000000 --- a/src/main/java/net/Indyuce/mmocore/skill/list/Combo_Attack.java +++ /dev/null @@ -1,56 +0,0 @@ -package net.Indyuce.mmocore.skill.list; - -import io.lumine.mythic.lib.damage.DamageType; -import net.Indyuce.mmocore.MMOCore; -import net.Indyuce.mmocore.api.util.math.formula.LinearValue; -import net.Indyuce.mmocore.skill.CasterMetadata; -import net.Indyuce.mmocore.skill.Skill; -import net.Indyuce.mmocore.skill.metadata.SkillMetadata; -import net.Indyuce.mmocore.skill.metadata.TargetSkillMetadata; -import org.bukkit.Material; -import org.bukkit.Particle; -import org.bukkit.Sound; -import org.bukkit.entity.LivingEntity; -import org.bukkit.scheduler.BukkitRunnable; - -public class Combo_Attack extends Skill { - public Combo_Attack() { - super(); - - setMaterial(Material.IRON_SWORD); - setLore("Violenty slashes your target &8{count}", "times for a total of &8{damage} &7damage.", "", "&e{cooldown}s Cooldown", "&9Costs {mana} {mana_name}"); - - addModifier("cooldown", new LinearValue(20, -.1, 5, 20)); - addModifier("damage", new LinearValue(9, .3)); - addModifier("count", new LinearValue(3, .2)); - addModifier("mana", new LinearValue(10, -.1, 3, 5)); - } - - @Override - public SkillMetadata whenCast(CasterMetadata caster, SkillInfo skill) { - TargetSkillMetadata cast = new TargetSkillMetadata(caster, skill, 3); - if (!cast.isSuccessful()) - return cast; - - new BukkitRunnable() { - final int count = (int) cast.getModifier("count"); - final double damage = cast.getModifier("damage") / count; - final LivingEntity target = cast.getTarget(); - - int c; - - @Override - public void run() { - if (c++ > count || caster.getPlayerData().isOnline()) { - cancel(); - return; - } - - target.getWorld().playSound(target.getLocation(), Sound.ENTITY_PLAYER_ATTACK_KNOCKBACK, 1, 2); - target.getWorld().spawnParticle(Particle.CRIT, target.getLocation().add(0, target.getHeight() / 2, 0), 24, 0, 0, 0, .7); - caster.attack(target, damage, DamageType.SKILL, DamageType.PHYSICAL); - } - }.runTaskTimer(MMOCore.plugin, 0, 5); - return cast; - } -} diff --git a/src/main/java/net/Indyuce/mmocore/skill/list/Control.java b/src/main/java/net/Indyuce/mmocore/skill/list/Control.java deleted file mode 100644 index 6c9ea03e..00000000 --- a/src/main/java/net/Indyuce/mmocore/skill/list/Control.java +++ /dev/null @@ -1,103 +0,0 @@ -package net.Indyuce.mmocore.skill.list; - -import io.lumine.mythic.lib.version.VersionMaterial; -import io.lumine.mythic.lib.version.VersionSound; -import net.Indyuce.mmocore.MMOCore; -import net.Indyuce.mmocore.api.util.math.formula.LinearValue; -import net.Indyuce.mmocore.skill.CasterMetadata; -import net.Indyuce.mmocore.skill.Skill; -import net.Indyuce.mmocore.skill.metadata.SkillMetadata; -import net.Indyuce.mmocore.skill.metadata.TargetSkillMetadata; -import org.bukkit.Bukkit; -import org.bukkit.Particle; -import org.bukkit.Sound; -import org.bukkit.entity.LivingEntity; -import org.bukkit.event.EventHandler; -import org.bukkit.event.HandlerList; -import org.bukkit.event.Listener; -import org.bukkit.event.player.PlayerInteractEvent; -import org.bukkit.potion.PotionEffect; -import org.bukkit.potion.PotionEffectType; -import org.bukkit.scheduler.BukkitRunnable; -import org.bukkit.util.Vector; - -public class Control extends Skill { - public Control() { - super(); - setMaterial(VersionMaterial.MAGENTA_DYE.toMaterial()); - setLore("Your target is temporarily slowed for &8{duration} &7seconds.", "As soon as you left click, it gets", "pushed back where you are looking at.", "Knockback force: &f{knockback}%", "", "&e{cooldown}s Cooldown", "&9Costs {mana} {mana_name}"); - - addModifier("cooldown", new LinearValue(18, -.3, 10, 20)); - addModifier("mana", new LinearValue(15, 1.5)); - addModifier("knockback", new LinearValue(30, 3)); - addModifier("duration", new LinearValue(2, 0)); - } - - @Override - public SkillMetadata whenCast(CasterMetadata caster, SkillInfo skill) { - TargetSkillMetadata cast = new TargetSkillMetadata(caster, skill, 7); - if (!cast.isSuccessful()) - return cast; - - caster.getPlayer().getWorld().playSound(caster.getPlayer().getLocation(), Sound.BLOCK_END_PORTAL_FRAME_FILL, 1, 1); - cast.getTarget().addPotionEffect(new PotionEffect(PotionEffectType.SLOW, 20 * 2, 0)); - new TelekinesyRunnable(caster, cast.getTarget(), cast.getModifier("knockback") / 100, cast.getModifier("duration")); - return cast; - } - - public static class TelekinesyRunnable extends BukkitRunnable implements Listener { - private final LivingEntity entity; - private final CasterMetadata caster; - - private final double f, d; - - private int j; - - public TelekinesyRunnable(CasterMetadata caster, LivingEntity entity, double force, double duration) { - this.entity = entity; - this.caster = caster; - - d = duration * 20; - f = force; - - runTaskTimer(MMOCore.plugin, 0, 1); - Bukkit.getPluginManager().registerEvents(this, MMOCore.plugin); - } - - @EventHandler - public void a(PlayerInteractEvent event) { - if (event.getPlayer().equals(caster.getPlayer()) && event.getAction().name().contains("LEFT_CLICK")) { - Vector vec = caster.getPlayer().getEyeLocation().getDirection().multiply(3 * f); - vec.setY(Math.max(.5, vec.getY() / 2)); - entity.setVelocity(vec); - - /* - * try not to interfere with other potion effects - */ - PotionEffect effect = entity.getPotionEffect(PotionEffectType.SLOW); - if (effect.getDuration() < d && effect.getAmplifier() == 0) - entity.removePotionEffect(PotionEffectType.SLOW); - - entity.getWorld().spawnParticle(Particle.SPELL_WITCH, entity.getLocation().add(0, entity.getHeight() / 2, 0), 16); - entity.getWorld().playSound(entity.getLocation(), VersionSound.ENTITY_FIREWORK_ROCKET_BLAST.toSound(), 2, 1); - close(); - } - } - - @Override - public void run() { - if (!caster.getPlayerData().isOnline() || entity.isDead() || j++ >= d) { - close(); - return; - } - - double a = (double) j / 3; - entity.getWorld().spawnParticle(Particle.SPELL_WITCH, entity.getLocation().add(Math.cos(a), entity.getHeight() / 2, Math.sin(a)), 0); - } - - private void close() { - cancel(); - HandlerList.unregisterAll(this); - } - } -} diff --git a/src/main/java/net/Indyuce/mmocore/skill/list/Deep_Wound.java b/src/main/java/net/Indyuce/mmocore/skill/list/Deep_Wound.java deleted file mode 100644 index 830ad7a2..00000000 --- a/src/main/java/net/Indyuce/mmocore/skill/list/Deep_Wound.java +++ /dev/null @@ -1,47 +0,0 @@ -package net.Indyuce.mmocore.skill.list; - -import io.lumine.mythic.lib.damage.DamageType; -import net.Indyuce.mmocore.api.util.math.formula.LinearValue; -import net.Indyuce.mmocore.skill.CasterMetadata; -import net.Indyuce.mmocore.skill.Skill; -import net.Indyuce.mmocore.skill.metadata.SkillMetadata; -import net.Indyuce.mmocore.skill.metadata.TargetSkillMetadata; -import org.bukkit.Material; -import org.bukkit.Particle; -import org.bukkit.Sound; -import org.bukkit.attribute.Attribute; -import org.bukkit.entity.LivingEntity; - -public class Deep_Wound extends Skill { - public Deep_Wound() { - super(); - setMaterial(Material.REDSTONE); - setLore("You puncture your target, dealing &c{damage} &7damage.", "Damage is increased up to &c+{extra}% &7based", - "on your target's missing health.", "", "&e{cooldown}s Cooldown", "&9Costs {mana} {mana_name}"); - - addModifier("cooldown", new LinearValue(20, -.1, 5, 20)); - addModifier("mana", new LinearValue(8, 3)); - addModifier("damage", new LinearValue(5, 1.5)); - addModifier("extra", new LinearValue(50, 20)); - } - - @Override - public SkillMetadata whenCast(CasterMetadata caster, SkillInfo skill) { - TargetSkillMetadata cast = new TargetSkillMetadata(caster, skill, 3); - if (!cast.isSuccessful()) - return cast; - - LivingEntity target = cast.getTarget(); - target.getWorld().playSound(target.getLocation(), Sound.ENTITY_ZOMBIE_ATTACK_IRON_DOOR, 2, 2); - target.getWorld().spawnParticle(Particle.CRIT, target.getLocation().add(0, target.getHeight() / 2, 0), 32, 0, 0, 0, .7); - target.getWorld().spawnParticle(Particle.BLOCK_CRACK, target.getLocation().add(0, target.getHeight() / 2, 0), 32, 0, 0, 0, 2, - Material.REDSTONE_BLOCK.createBlockData()); - - double max = target.getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue(); - double ratio = (max - target.getHealth()) / max; - - double damage = cast.getModifier("damage") * (1 + cast.getModifier("extra") * ratio / 100); - caster.attack(target, damage, DamageType.SKILL, DamageType.PHYSICAL); - return cast; - } -} diff --git a/src/main/java/net/Indyuce/mmocore/skill/list/Empowered_Attack.java b/src/main/java/net/Indyuce/mmocore/skill/list/Empowered_Attack.java deleted file mode 100644 index fac43136..00000000 --- a/src/main/java/net/Indyuce/mmocore/skill/list/Empowered_Attack.java +++ /dev/null @@ -1,119 +0,0 @@ -package net.Indyuce.mmocore.skill.list; - -import io.lumine.mythic.lib.api.event.PlayerAttackEvent; -import io.lumine.mythic.lib.damage.DamageType; -import io.lumine.mythic.lib.version.VersionMaterial; -import io.lumine.mythic.lib.version.VersionSound; -import net.Indyuce.mmocore.MMOCore; -import net.Indyuce.mmocore.api.util.MMOCoreUtils; -import net.Indyuce.mmocore.api.util.math.formula.LinearValue; -import net.Indyuce.mmocore.api.util.math.particle.SmallParticleEffect; -import net.Indyuce.mmocore.skill.CasterMetadata; -import net.Indyuce.mmocore.skill.Skill; -import net.Indyuce.mmocore.skill.metadata.SkillMetadata; -import org.bukkit.Bukkit; -import org.bukkit.Location; -import org.bukkit.Particle; -import org.bukkit.Sound; -import org.bukkit.entity.Entity; -import org.bukkit.entity.LivingEntity; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.util.Vector; - -public class Empowered_Attack extends Skill { - private static final double perb = 5; - - public Empowered_Attack() { - super(); - setMaterial(VersionMaterial.BONE_MEAL.toMaterial()); - setLore("You charge your weapon with lightning.", "Your next attack deals &f{extra}% &7extra damage", "and spreads to enemies within &f{radius} &7blocks", "for &f{ratio}% &7of the initial damage.", "", "&e{cooldown}s Cooldown", "&9Costs {mana} {mana_name}"); - - addModifier("cooldown", new LinearValue(10, -.2, 5, 10)); - addModifier("mana", new LinearValue(4, 1)); - addModifier("radius", new LinearValue(4, 0)); - addModifier("ratio", new LinearValue(30, 10, 30, 100)); - addModifier("extra", new LinearValue(30, 8)); - } - - @Override - public SkillMetadata whenCast(CasterMetadata caster, SkillInfo skill) { - SkillMetadata cast = new SkillMetadata(caster, skill); - if (!cast.isSuccessful()) - return cast; - - caster.getPlayer().playSound(caster.getPlayer().getLocation(), Sound.BLOCK_END_PORTAL_FRAME_FILL, 1, 1); - new EmpoweredAttack(caster, cast.getModifier("extra"), cast.getModifier("ratio"), cast.getModifier("radius")); - return cast; - } - - private void drawVector(Location loc, Vector vec) { - - double steps = vec.length() * perb; - Vector v = vec.clone().normalize().multiply((double) 1 / perb); - - for (int j = 0; j < Math.min(steps, 124); j++) - loc.getWorld().spawnParticle(Particle.FIREWORKS_SPARK, loc.add(v), 0); - } - - public class EmpoweredAttack implements Listener { - private final CasterMetadata caster; - private final double c, r, rad; - - public EmpoweredAttack(CasterMetadata caster, double extra, double ratio, double radius) { - this.caster = caster; - this.c = 1 + extra / 100; - this.r = ratio / 100; - this.rad = radius; - - if (caster.getPlayerData().isOnline()) - new SmallParticleEffect(caster.getPlayer(), Particle.FIREWORKS_SPARK); - - Bukkit.getPluginManager().registerEvents(this, MMOCore.plugin); - Bukkit.getScheduler().scheduleSyncDelayedTask(MMOCore.plugin, this::close, 80); - } - - private void close() { - PlayerAttackEvent.getHandlerList().unregister(this); - } - - @EventHandler - public void a(PlayerAttackEvent event) { - if (!caster.getPlayerData().isOnline()) return; - if (event.getPlayer().equals(caster.getPlayer()) && event.getAttack().getDamage().hasType(DamageType.WEAPON)) { - close(); - - Entity target = event.getEntity(); - - /* - * play lightning effect - */ - final Location loc = target.getLocation().add(0, target.getHeight() / 2, 0); - for (int j = 0; j < 3; j++) { - Location clone = loc.clone(); - double a = random.nextDouble() * Math.PI * 2; - loc.add(Math.cos(a), 5, Math.sin(a)); - drawVector(clone, loc.clone().subtract(clone).toVector()); - } - - target.getWorld().playSound(target.getLocation(), VersionSound.ENTITY_FIREWORK_ROCKET_BLAST.toSound(), 2, .5f); - target.getWorld().spawnParticle(Particle.FIREWORKS_SPARK, target.getLocation().add(0, target.getHeight() / 2, 0), 32, 0, 0, 0, .2); - - double sweep = event.getAttack().getDamage().getDamage() * r; - Location src = target.getLocation().add(0, target.getHeight() / 2, 0); - - for (Entity entity : target.getNearbyEntities(rad, rad, rad)) - if (MMOCoreUtils.canTarget(caster.getPlayerData(), entity)) { - drawVector(src, entity.getLocation().add(0, entity.getHeight() / 2, 0).subtract(src).toVector()); - caster.attack((LivingEntity) entity, sweep, DamageType.PHYSICAL, DamageType.SKILL); - } - - /* - * Apply damage afterwards otherwise the damage dealt to nearby - * entities scale with the extra ability damage. - */ - event.getAttack().getDamage().multiply(1 + c, DamageType.WEAPON); - } - } - } -} diff --git a/src/main/java/net/Indyuce/mmocore/skill/list/Evade.java b/src/main/java/net/Indyuce/mmocore/skill/list/Evade.java deleted file mode 100644 index 13fabe1e..00000000 --- a/src/main/java/net/Indyuce/mmocore/skill/list/Evade.java +++ /dev/null @@ -1,83 +0,0 @@ -package net.Indyuce.mmocore.skill.list; - -import io.lumine.mythic.lib.api.event.PlayerAttackEvent; -import io.lumine.mythic.lib.damage.DamageType; -import io.lumine.mythic.lib.version.VersionSound; -import net.Indyuce.mmocore.MMOCore; -import net.Indyuce.mmocore.api.player.PlayerData; -import net.Indyuce.mmocore.api.util.math.formula.LinearValue; -import net.Indyuce.mmocore.api.util.math.particle.SmallParticleEffect; -import net.Indyuce.mmocore.skill.CasterMetadata; -import net.Indyuce.mmocore.skill.Skill; -import net.Indyuce.mmocore.skill.metadata.SkillMetadata; -import org.bukkit.Bukkit; -import org.bukkit.Material; -import org.bukkit.Particle; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; -import org.bukkit.event.entity.EntityDamageEvent; -import org.bukkit.scheduler.BukkitRunnable; - -public class Evade extends Skill { - public Evade() { - super(); - setMaterial(Material.LEATHER_BOOTS); - setLore("You become imune to damage for &8{duration} &7seconds.", "Cancels when dealing weapon damage.", "", "&e{cooldown}s Cooldown", - "&9Costs {mana} {mana_name}"); - - addModifier("cooldown", new LinearValue(20, 0)); - addModifier("mana", new LinearValue(8, 3)); - addModifier("duration", new LinearValue(2, .3, 2, 10)); - } - - @Override - public SkillMetadata whenCast(CasterMetadata caster, SkillInfo skill) { - SkillMetadata cast = new SkillMetadata(caster, skill); - if (!cast.isSuccessful()) - return cast; - - caster.getPlayer().getWorld().playSound(caster.getPlayer().getLocation(), VersionSound.ENTITY_ENDERMAN_TELEPORT.toSound(), 1, 2); - new SmallParticleEffect(caster.getPlayer(), Particle.CLOUD); - new EvadeSkill(caster.getPlayerData(), cast.getModifier("duration")); - return cast; - } - - private static class EvadeSkill extends BukkitRunnable implements Listener { - private final PlayerData data; - - public EvadeSkill(PlayerData data, double duration) { - this.data = data; - - Bukkit.getPluginManager().registerEvents(this, MMOCore.plugin); - runTaskTimer(MMOCore.plugin, 0, 1); - Bukkit.getScheduler().runTaskLater(MMOCore.plugin, this::close, (long) (duration * 20)); - } - - private void close() { - cancel(); - EntityDamageEvent.getHandlerList().unregister(this); - } - - @EventHandler(priority = EventPriority.LOW) - public void a(EntityDamageEvent event) { - if (!data.isOnline()) return; - if (event.getEntity().equals(data.getPlayer())) - event.setCancelled(true); - } - - @EventHandler(priority = EventPriority.HIGHEST) - public void b(PlayerAttackEvent event) { - if (event.getAttack().getDamage().hasType(DamageType.WEAPON) && !event.isCancelled() && PlayerData.get(event.getData().getUniqueId()).equals(data)) - close(); - } - - @Override - public void run() { - if (!data.isOnline() || data.getPlayer().isDead()) - close(); - else - data.getPlayer().getWorld().spawnParticle(Particle.CLOUD, data.getPlayer().getLocation().add(0, 1, 0), 0); - } - } -} diff --git a/src/main/java/net/Indyuce/mmocore/skill/list/Fire_Berserker.java b/src/main/java/net/Indyuce/mmocore/skill/list/Fire_Berserker.java deleted file mode 100644 index bd95574f..00000000 --- a/src/main/java/net/Indyuce/mmocore/skill/list/Fire_Berserker.java +++ /dev/null @@ -1,37 +0,0 @@ -package net.Indyuce.mmocore.skill.list; - -import io.lumine.mythic.lib.api.event.PlayerAttackEvent; -import net.Indyuce.mmocore.MMOCore; -import net.Indyuce.mmocore.api.player.PlayerData; -import net.Indyuce.mmocore.api.util.math.formula.LinearValue; -import net.Indyuce.mmocore.skill.PassiveSkill; -import org.bukkit.Bukkit; -import org.bukkit.Material; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; - -import java.util.Optional; - -public class Fire_Berserker extends PassiveSkill { - public Fire_Berserker() { - super(); - setMaterial(Material.FLINT_AND_STEEL); - setLore("You deal &c{extra}% &7more damage when on fire."); - setPassive(); - - addModifier("extra", new LinearValue(10, 5)); - // addModifier("duration", new LinearValue(10, .1)); - // addModifier("cooldown", new LinearValue(30, 0)); - - Bukkit.getPluginManager().registerEvents(this, MMOCore.plugin); - } - - @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) - public void a(PlayerAttackEvent event) { - PlayerData data = PlayerData.get(event.getData().getUniqueId()); - if (event.getPlayer().getFireTicks() > 0) { - Optional skill = data.getProfess().findSkill(this); - skill.ifPresent(skillInfo -> event.getAttack().getDamage().multiply(1 + skillInfo.getModifier("extra", data.getSkillLevel(this)) / 100)); - } - } -} diff --git a/src/main/java/net/Indyuce/mmocore/skill/list/Fire_Rage.java b/src/main/java/net/Indyuce/mmocore/skill/list/Fire_Rage.java deleted file mode 100644 index ca3e5b66..00000000 --- a/src/main/java/net/Indyuce/mmocore/skill/list/Fire_Rage.java +++ /dev/null @@ -1,158 +0,0 @@ -package net.Indyuce.mmocore.skill.list; - -import io.lumine.mythic.lib.MythicLib; -import io.lumine.mythic.lib.api.player.EquipmentSlot; -import io.lumine.mythic.lib.api.stat.StatMap; -import io.lumine.mythic.lib.damage.DamageType; -import io.lumine.mythic.lib.version.VersionMaterial; -import io.lumine.mythic.lib.version.VersionSound; -import net.Indyuce.mmocore.MMOCore; -import net.Indyuce.mmocore.api.util.MMOCoreUtils; -import net.Indyuce.mmocore.api.util.math.VectorRotation; -import net.Indyuce.mmocore.api.util.math.formula.LinearValue; -import net.Indyuce.mmocore.skill.CasterMetadata; -import net.Indyuce.mmocore.skill.Skill; -import net.Indyuce.mmocore.skill.metadata.SkillMetadata; -import org.bukkit.Bukkit; -import org.bukkit.Location; -import org.bukkit.Particle; -import org.bukkit.Sound; -import org.bukkit.entity.Entity; -import org.bukkit.entity.LivingEntity; -import org.bukkit.event.EventHandler; -import org.bukkit.event.HandlerList; -import org.bukkit.event.Listener; -import org.bukkit.event.player.PlayerInteractEvent; -import org.bukkit.potion.PotionEffectType; -import org.bukkit.scheduler.BukkitRunnable; -import org.bukkit.util.Vector; - -public class Fire_Rage extends Skill { - public Fire_Rage() { - super(); - setMaterial(VersionMaterial.FIRE_CHARGE.toMaterial()); - setLore("For {duration} seconds, you slow down and are able", "to cast up to {count} fireballs by left clicking.", "", "Fireballs deal &c{damage} &7damage upon contact", "and ignite your target for &c{ignite} &7seconds.", "&e{cooldown}s Cooldown", "&9Costs {mana} {mana_name}"); - - addModifier("duration", new LinearValue(8, 0)); - addModifier("count", new LinearValue(4, 0)); - addModifier("mana", new LinearValue(15, 1)); - addModifier("damage", new LinearValue(5, 3)); - addModifier("ignite", new LinearValue(2, .1)); - addModifier("cooldown", new LinearValue(9, -.1, 1, 5)); - } - - @Override - public SkillMetadata whenCast(CasterMetadata caster, SkillInfo skill) { - SkillMetadata cast = new SkillMetadata(caster, skill); - if (!cast.isSuccessful()) - return cast; - - new Rage(caster, cast); - return cast; - } - - public class Rage extends BukkitRunnable implements Listener { - private final CasterMetadata caster; - private final StatMap.CachedStatMap cachedStats; - private final int count, ignite; - private final double damage; - - private int c; - private double b; - private long last = System.currentTimeMillis(); - - /* - * time the player needs to wait before firing two fireballs. - */ - private static final long timeOut = 700; - - public Rage(CasterMetadata caster, SkillMetadata cast) { - this.caster = caster; - this.cachedStats = caster.getPlayerData().getMMOPlayerData().getStatMap().cache(EquipmentSlot.MAIN_HAND); - this.ignite = (int) (20 * cast.getModifier("ignite")); - this.damage = cast.getModifier("damage"); - c = count = (int) cast.getModifier("count"); - - Bukkit.getPluginManager().registerEvents(this, MMOCore.plugin); - Bukkit.getScheduler().runTaskLater(MMOCore.plugin, this::close, (long) (cast.getModifier("duration") * 20)); - runTaskTimer(MMOCore.plugin, 0, 1); - } - - @EventHandler - public void a(PlayerInteractEvent event) { - if (event.getPlayer().equals(caster.getPlayer()) && event.getAction().name().contains("LEFT_CLICK") && (System.currentTimeMillis() - last) > timeOut) { - last = System.currentTimeMillis(); - castEffect(); - fireball(c < 2); - if (c-- < 2) - close(); - } - } - - private void castEffect() { - VectorRotation rotation = new VectorRotation(caster.getPlayer().getEyeLocation()); - for (double a = 0; a < Math.PI * 2; a += Math.PI / 13) { - Vector vec = rotation.rotate(new Vector(Math.cos(a), Math.sin(a), 0)).add(caster.getPlayer().getEyeLocation().getDirection().multiply(.5)).multiply(.3); - caster.getPlayer().getWorld().spawnParticle(Particle.FLAME, caster.getPlayer().getLocation().add(0, 1.3, 0).add(caster.getPlayer().getEyeLocation().getDirection().multiply(.5)), 0, vec.getX(), vec.getY(), vec.getZ(), .3); - } - } - - private void close() { - if (isCancelled()) - return; - - cancel(); - HandlerList.unregisterAll(this); - } - - private void fireball(boolean last) { - if (last) { - caster.getPlayer().removePotionEffect(PotionEffectType.SLOW); - caster.getPlayer().removePotionEffect(PotionEffectType.SLOW); - } - - caster.getPlayer().getWorld().playSound(caster.getPlayer().getLocation(), VersionSound.ENTITY_FIREWORK_ROCKET_BLAST.toSound(), 1, last ? 0 : 1); - new BukkitRunnable() { - int j = 0; - final Vector vec = caster.getPlayer().getEyeLocation().getDirection(); - final Location loc = caster.getPlayer().getLocation().add(0, 1.3, 0); - - public void run() { - if (j++ > 40) - cancel(); - - loc.add(vec); - - if (j % 2 == 0) - loc.getWorld().playSound(loc, Sound.BLOCK_FIRE_AMBIENT, 2, 1); - loc.getWorld().spawnParticle(Particle.FLAME, loc, 4, .1, .1, .1, 0); - loc.getWorld().spawnParticle(Particle.LAVA, loc, 0); - - for (Entity target : MMOCoreUtils.getNearbyChunkEntities(loc)) - if (MythicLib.plugin.getVersion().getWrapper().isInBoundingBox(target, loc) && MMOCoreUtils.canTarget(caster.getPlayerData(), target)) { - loc.getWorld().spawnParticle(Particle.LAVA, loc, 8); - loc.getWorld().spawnParticle(Particle.FLAME, loc, 32, 0, 0, 0, .1); - loc.getWorld().playSound(loc, Sound.ENTITY_BLAZE_HURT, 2, 1); - target.setFireTicks(target.getFireTicks() + ignite); - caster.attack((LivingEntity) target, damage, DamageType.SKILL, DamageType.PROJECTILE, DamageType.MAGIC); - cancel(); - } - } - }.runTaskTimer(MMOCore.plugin, 0, 1); - } - - @Override - public void run() { - if (caster.getPlayer().isDead() || !caster.getPlayer().isOnline()) { - close(); - return; - } - - b += Math.PI / 30; - for (int j = 0; j < c; j++) { - double a = Math.PI * 2 * j / count + b; - caster.getPlayer().spawnParticle(Particle.FLAME, caster.getPlayer().getLocation().add(Math.cos(a) * 1.5, 1 + Math.sin(a * 1.5) * .7, Math.sin(a) * 1.5), 0); - } - } - } -} diff --git a/src/main/java/net/Indyuce/mmocore/skill/list/Fire_Storm.java b/src/main/java/net/Indyuce/mmocore/skill/list/Fire_Storm.java deleted file mode 100644 index b69a9918..00000000 --- a/src/main/java/net/Indyuce/mmocore/skill/list/Fire_Storm.java +++ /dev/null @@ -1,77 +0,0 @@ -package net.Indyuce.mmocore.skill.list; - -import io.lumine.mythic.lib.damage.DamageType; -import io.lumine.mythic.lib.version.VersionSound; -import net.Indyuce.mmocore.MMOCore; -import net.Indyuce.mmocore.api.util.math.formula.LinearValue; -import net.Indyuce.mmocore.api.util.math.particle.ParabolicProjectile; -import net.Indyuce.mmocore.skill.CasterMetadata; -import net.Indyuce.mmocore.skill.Skill; -import net.Indyuce.mmocore.skill.metadata.SkillMetadata; -import net.Indyuce.mmocore.skill.metadata.TargetSkillMetadata; -import org.bukkit.Material; -import org.bukkit.Particle; -import org.bukkit.Sound; -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Player; -import org.bukkit.scheduler.BukkitRunnable; -import org.bukkit.util.Vector; - -public class Fire_Storm extends Skill { - public Fire_Storm() { - super(); - setMaterial(Material.BLAZE_POWDER); - setLore("Casts a flurry of 6 fire projectiles onto", "nearby enemies, proritizing the initial", - "target. Each projectile deals &c{damage} &7damage", "and ignite the target for &c{ignite} &7seconds.", "", - "&e{cooldown}s Cooldown", "&9Costs {mana} {mana_name}"); - - addModifier("mana", new LinearValue(15, 2)); - addModifier("damage", new LinearValue(5, 3)); - addModifier("ignite", new LinearValue(2, .1)); - addModifier("cooldown", new LinearValue(5, -.1, 1, 5)); - } - - @Override - public SkillMetadata whenCast(CasterMetadata caster, SkillInfo skill) { - TargetSkillMetadata cast = new TargetSkillMetadata(caster, skill, 20); - if (!cast.isSuccessful()) return cast; - - LivingEntity target = cast.getTarget(); - - final double damage = cast.getModifier("damage"); - final int ignite = (int) (20 * cast.getModifier("ignite")); - - caster.getPlayer().getWorld().playSound(caster.getPlayer().getLocation(), VersionSound.ENTITY_FIREWORK_ROCKET_BLAST.toSound(), 1, 1); - new BukkitRunnable() { - int j = 0; - - @Override - public void run() { - if (j++ > 5 || caster.getPlayer().isDead() || !caster.getPlayer().isOnline() || target.isDead() || !caster.getPlayer().getWorld() - .equals(target.getWorld())) { - cancel(); - return; - } - - // TODO dynamic target location - - caster.getPlayer().getWorld().playSound(caster.getPlayer().getLocation(), Sound.BLOCK_FIRE_AMBIENT, 1, 1); - new ParabolicProjectile(caster.getPlayer().getLocation().add(0, 1, 0), target.getLocation().add(0, target.getHeight() / 2, 0), - randomVector(caster.getPlayer()), () -> { - target.getWorld().playSound(target.getLocation(), VersionSound.ENTITY_FIREWORK_ROCKET_TWINKLE.toSound(), 1, 2); - target.getWorld().spawnParticle(Particle.SMOKE_NORMAL, target.getLocation().add(0, target.getHeight() / 2, 0), 8, 0, 0, 0, .15); - caster.attack(target, damage, DamageType.SKILL, DamageType.PROJECTILE, DamageType.MAGIC); - target.setFireTicks(ignite); - - }, 2, Particle.FLAME); - } - }.runTaskTimer(MMOCore.plugin, 0, 4); - return cast; - } - - private Vector randomVector(Player player) { - double a = Math.toRadians(player.getEyeLocation().getYaw() + 90); - a += (random.nextBoolean() ? 1 : -1) * (random.nextDouble() * 2 + 1) * Math.PI / 6; - return new Vector(Math.cos(a), .8, Math.sin(a)).normalize().multiply(.4); - } -} diff --git a/src/main/java/net/Indyuce/mmocore/skill/list/Fireball.java b/src/main/java/net/Indyuce/mmocore/skill/list/Fireball.java deleted file mode 100644 index bf797a17..00000000 --- a/src/main/java/net/Indyuce/mmocore/skill/list/Fireball.java +++ /dev/null @@ -1,104 +0,0 @@ -package net.Indyuce.mmocore.skill.list; - -import io.lumine.mythic.lib.MythicLib; -import io.lumine.mythic.lib.api.MMORayTraceResult; -import io.lumine.mythic.lib.damage.DamageType; -import io.lumine.mythic.lib.version.VersionMaterial; -import io.lumine.mythic.lib.version.VersionSound; -import net.Indyuce.mmocore.MMOCore; -import net.Indyuce.mmocore.api.util.MMOCoreUtils; -import net.Indyuce.mmocore.api.util.math.formula.LinearValue; -import net.Indyuce.mmocore.skill.CasterMetadata; -import net.Indyuce.mmocore.skill.Skill; -import net.Indyuce.mmocore.skill.metadata.SkillMetadata; -import org.bukkit.Location; -import org.bukkit.Particle; -import org.bukkit.Sound; -import org.bukkit.entity.Entity; -import org.bukkit.entity.LivingEntity; -import org.bukkit.scheduler.BukkitRunnable; -import org.bukkit.util.Vector; - -public class Fireball extends Skill { - public Fireball() { - super(); - setMaterial(VersionMaterial.FIRE_CHARGE.toMaterial()); - setLore("Casts a deadly fireball onto your", "target, dealing &c{damage} &7damage upon contact", "and igniting it for &c{ignite} &7seconds.", "", "Shatters into 3 blazing hot shards which stick", "to walls and explode 3 seconds later, dealing", "&c{ratio}% &7of the initial spell damage.", "", "&e{cooldown}s Cooldown", "&9Costs {mana} {mana_name}"); - - addModifier("mana", new LinearValue(15, 1)); - addModifier("damage", new LinearValue(5, 3)); - addModifier("ignite", new LinearValue(2, .1)); - addModifier("ratio", new LinearValue(50, 3)); - addModifier("cooldown", new LinearValue(9, -.1, 1, 5)); - } - - @Override - public SkillMetadata whenCast(CasterMetadata caster, SkillInfo skill) { - SkillMetadata cast = new SkillMetadata(caster, skill); - if (!cast.isSuccessful()) - return cast; - - caster.getPlayer().getWorld().playSound(caster.getPlayer().getLocation(), VersionSound.ENTITY_FIREWORK_ROCKET_BLAST.toSound(), 1, 1); - new BukkitRunnable() { - int j = 0; - final Vector vec = caster.getPlayer().getEyeLocation().getDirection(); - final Location loc = caster.getPlayer().getLocation().add(0, 1.3, 0); - - public void run() { - if (j++ > 40) { - cancel(); - return; - } - - loc.add(vec); - - if (j % 3 == 0) - loc.getWorld().playSound(loc, Sound.BLOCK_FIRE_AMBIENT, 2, 1); - loc.getWorld().spawnParticle(Particle.FLAME, loc, 4, .02, .02, .02, 0); - loc.getWorld().spawnParticle(Particle.LAVA, loc, 0); - - for (Entity target : MMOCoreUtils.getNearbyChunkEntities(loc)) - if (MythicLib.plugin.getVersion().getWrapper().isInBoundingBox(target, loc) && MMOCoreUtils.canTarget(caster.getPlayerData(), target)) { - loc.getWorld().spawnParticle(Particle.LAVA, loc, 8); - loc.getWorld().spawnParticle(Particle.FLAME, loc, 32, 0, 0, 0, .1); - loc.getWorld().playSound(loc, Sound.ENTITY_BLAZE_HURT, 2, 1); - target.setFireTicks((int) (target.getFireTicks() + cast.getModifier("ignite") * 20)); - double damage = cast.getModifier("damage"); - caster.attack((LivingEntity) target, damage, DamageType.SKILL, DamageType.PROJECTILE, DamageType.MAGIC); - - new BukkitRunnable() { - int i = 0; - - @Override - public void run() { - if (i++ > 2) { - cancel(); - return; - } - - double range = 2.5 * (1 + random.nextDouble()); - Vector dir = randomDirection(); - loc.getWorld().playSound(loc, Sound.ENTITY_BLAZE_HURT, 2, 1.5f); - - MMORayTraceResult result = MythicLib.plugin.getVersion().getWrapper().rayTrace(loc, dir, range, entity -> MMOCoreUtils.canTarget(caster.getPlayerData(), entity)); - if (result.hasHit()) - caster.attack(result.getHit(), damage, DamageType.SKILL, DamageType.PROJECTILE, DamageType.MAGIC); - result.draw(loc.clone(), dir, 8, tick -> tick.getWorld().spawnParticle(Particle.FLAME, tick, 0)); - - } - }.runTaskTimer(MMOCore.plugin, 3, 3); - - cancel(); - return; - } - } - }.runTaskTimer(MMOCore.plugin, 0, 1); - return cast; - } - - private Vector randomDirection() { - double x = random.nextDouble() - .5, y = (random.nextDouble() - .2) / 2, z = random.nextDouble() - .5; - Vector dir = new Vector(x, y, z); - return dir.lengthSquared() == 0 ? new Vector(1, 0, 0) : dir.normalize(); - } -} diff --git a/src/main/java/net/Indyuce/mmocore/skill/list/Furtive_Strike.java b/src/main/java/net/Indyuce/mmocore/skill/list/Furtive_Strike.java deleted file mode 100644 index 9384b224..00000000 --- a/src/main/java/net/Indyuce/mmocore/skill/list/Furtive_Strike.java +++ /dev/null @@ -1,50 +0,0 @@ -package net.Indyuce.mmocore.skill.list; - -import io.lumine.mythic.lib.damage.DamageType; -import net.Indyuce.mmocore.api.util.math.formula.LinearValue; -import net.Indyuce.mmocore.api.util.math.particle.SmallParticleEffect; -import net.Indyuce.mmocore.skill.CasterMetadata; -import net.Indyuce.mmocore.skill.Skill; -import net.Indyuce.mmocore.skill.metadata.SkillMetadata; -import net.Indyuce.mmocore.skill.metadata.TargetSkillMetadata; -import org.bukkit.Material; -import org.bukkit.Particle; -import org.bukkit.Sound; -import org.bukkit.entity.LivingEntity; - -public class Furtive_Strike extends Skill { - public Furtive_Strike() { - super(); - setMaterial(Material.COAL); - setLore("Deals &c{damage} &7damage, increased by &c{extra}% &7if", "there are not any enemies within &c{radius} &7blocks.", "", "&e{cooldown}s Cooldown", "&9Costs {mana} {mana_name}"); - - addModifier("cooldown", new LinearValue(20, -.1, 5, 20)); - addModifier("mana", new LinearValue(8, 3)); - addModifier("damage", new LinearValue(5, 1.5)); - addModifier("extra", new LinearValue(50, 20)); - addModifier("radius", new LinearValue(7, 0)); - } - - @Override - public SkillMetadata whenCast(CasterMetadata caster, SkillInfo skill) { - TargetSkillMetadata cast = new TargetSkillMetadata(caster, skill, 3); - if (!cast.isSuccessful()) - return cast; - - LivingEntity target = cast.getTarget(); - target.getWorld().playSound(target.getLocation(), Sound.ENTITY_ZOMBIE_ATTACK_IRON_DOOR, 2, 1.5f); - target.getWorld().spawnParticle(Particle.CRIT, target.getLocation().add(0, target.getHeight() / 2, 0), 32, 0, 0, 0, .5); - target.getWorld().spawnParticle(Particle.SMOKE_NORMAL, target.getLocation().add(0, target.getHeight() / 2, 0), 64, 0, 0, 0, .08); - - double damage = cast.getModifier("damage"); - - double radius = cast.getModifier("radius"); - if (target.getNearbyEntities(radius, radius, radius).stream().allMatch(entity -> entity.equals(caster.getPlayer()))) { - new SmallParticleEffect(target, Particle.SPELL_WITCH); - damage *= 1 + cast.getModifier("extra") / 100; - } - - caster.attack(target, damage, DamageType.SKILL, DamageType.PHYSICAL); - return cast; - } -} diff --git a/src/main/java/net/Indyuce/mmocore/skill/list/Greater_Healings.java b/src/main/java/net/Indyuce/mmocore/skill/list/Greater_Healings.java deleted file mode 100644 index a302742f..00000000 --- a/src/main/java/net/Indyuce/mmocore/skill/list/Greater_Healings.java +++ /dev/null @@ -1,42 +0,0 @@ -package net.Indyuce.mmocore.skill.list; - -import io.lumine.mythic.lib.comp.target.InteractionType; -import net.Indyuce.mmocore.api.util.math.formula.LinearValue; -import net.Indyuce.mmocore.api.util.math.particle.SmallParticleEffect; -import net.Indyuce.mmocore.skill.CasterMetadata; -import net.Indyuce.mmocore.skill.Skill; -import net.Indyuce.mmocore.skill.metadata.SkillMetadata; -import net.Indyuce.mmocore.skill.metadata.TargetSkillMetadata; -import org.bukkit.Material; -import org.bukkit.Particle; -import org.bukkit.Sound; -import org.bukkit.attribute.Attribute; -import org.bukkit.entity.LivingEntity; - -public class Greater_Healings extends Skill { - public Greater_Healings() { - super(); - setMaterial(Material.GOLDEN_APPLE); - setLore("Instantly grants &a{heal} &7HP to the", "target. Sneak to cast it on yourself.", "", "&e{cooldown}s Cooldown", "&9Costs {mana} {mana_name}"); - - addModifier("mana", new LinearValue(4, 2)); - addModifier("heal", new LinearValue(10, 4)); - addModifier("cooldown", new LinearValue(9, -.1, 1, 5)); - } - - @Override - public SkillMetadata whenCast(CasterMetadata caster, SkillInfo skill) { - SkillMetadata cast = caster.getPlayer().isSneaking() ? new SkillMetadata(caster, skill) : new TargetSkillMetadata(caster, skill, 50, InteractionType.SUPPORT_SKILL); - if (!cast.isSuccessful()) - return cast; - - LivingEntity target = cast instanceof TargetSkillMetadata ? ((TargetSkillMetadata) cast).getTarget() : caster.getPlayer(); - - double max = target.getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue(); - target.setHealth(Math.min(max, target.getHealth() + cast.getModifier("heal"))); - - new SmallParticleEffect(target, Particle.HEART, 1); - target.getWorld().playSound(target.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 2, 2); - return cast; - } -} diff --git a/src/main/java/net/Indyuce/mmocore/skill/list/Human_Shield.java b/src/main/java/net/Indyuce/mmocore/skill/list/Human_Shield.java deleted file mode 100644 index 239b10e0..00000000 --- a/src/main/java/net/Indyuce/mmocore/skill/list/Human_Shield.java +++ /dev/null @@ -1,106 +0,0 @@ -package net.Indyuce.mmocore.skill.list; - -import io.lumine.mythic.lib.comp.target.InteractionType; -import io.lumine.mythic.lib.version.VersionMaterial; -import net.Indyuce.mmocore.MMOCore; -import net.Indyuce.mmocore.api.player.PlayerData; -import net.Indyuce.mmocore.api.util.math.formula.LinearValue; -import net.Indyuce.mmocore.skill.CasterMetadata; -import net.Indyuce.mmocore.skill.Skill; -import net.Indyuce.mmocore.skill.metadata.SkillMetadata; -import net.Indyuce.mmocore.skill.metadata.TargetSkillMetadata; -import org.bukkit.Bukkit; -import org.bukkit.Particle; -import org.bukkit.Sound; -import org.bukkit.attribute.Attribute; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.HandlerList; -import org.bukkit.event.Listener; -import org.bukkit.event.entity.EntityDamageEvent; -import org.bukkit.scheduler.BukkitRunnable; - -public class Human_Shield extends Skill { - public Human_Shield() { - super(); - setMaterial(VersionMaterial.TOTEM_OF_UNDYING.toMaterial()); - setLore("Casts a protection charm onto target ally,", "reducing damage taken by &a{reduction}%&7.", "&a{redirect}% &7of this damage is redirected to you.", "Charm is cancelled when reaching &c{low}%&7 health.", "Lasts &a{duration} &7seconds.", "", "&e{cooldown}s Cooldown", "&9Costs {mana} {mana_name}"); - - addModifier("cooldown", new LinearValue(18, -.3, 14, 18)); - addModifier("mana", new LinearValue(15, 1.5)); - addModifier("reduction", new LinearValue(30, 3, 30, 70)); - addModifier("redirect", new LinearValue(30, -2, 20, 30)); - addModifier("duration", new LinearValue(7, 0)); - addModifier("low", new LinearValue(10, 0)); - } - - @Override - public SkillMetadata whenCast(CasterMetadata caster, SkillInfo skill) { - TargetSkillMetadata cast = new TargetSkillMetadata(caster, skill, 7, InteractionType.SUPPORT_SKILL); - if (!cast.isSuccessful()) - return cast; - - if (!(cast.getTarget() instanceof Player)) { - cast.abort(); - return cast; - } - - caster.getPlayer().getWorld().playSound(caster.getPlayer().getLocation(), Sound.ENTITY_BLAZE_AMBIENT, 1, 1); - new HumanShield(caster.getPlayerData(), (Player) cast.getTarget(), cast.getModifier("reduction"), cast.getModifier("redirect"), cast.getModifier("duration"), cast.getModifier("low")); - return cast; - } - - public static class HumanShield extends BukkitRunnable implements Listener { - private final PlayerData data; - private final Player target; - private final double r, rd, d, l; - - private int j; - - public HumanShield(PlayerData data, Player target, double reduction, double redirect, double duration, double low) { - this.target = target; - this.data = data; - - r = 1 - Math.min(1, reduction / 100); - rd = redirect / 100; - d = duration * 20; - l = low / 100; - - runTaskTimer(MMOCore.plugin, 0, 1); - Bukkit.getPluginManager().registerEvents(this, MMOCore.plugin); - } - - @EventHandler - public void a(EntityDamageEvent event) { - if (event.getEntity().equals(target)) { - - double damage = event.getDamage() * r; - event.setDamage(damage); - - double health = data.getPlayer().getHealth() - damage * rd; - if (health > data.getPlayer().getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue() * l) - data.getPlayer().setHealth(health); - else { - data.getPlayer().setHealth(1); - close(); - } - } - } - - @Override - public void run() { - if (!data.isOnline() || data.getPlayer().isDead() || !target.isOnline() || target.isDead() || j++ >= d) { - close(); - return; - } - - double a = (double) j / 5; - target.getWorld().spawnParticle(Particle.VILLAGER_HAPPY, target.getLocation().add(Math.cos(a), 1 + Math.sin(a / 3) / 1.3, Math.sin(a)), 0); - } - - private void close() { - cancel(); - HandlerList.unregisterAll(this); - } - } -} diff --git a/src/main/java/net/Indyuce/mmocore/skill/list/Ice_Spikes.java b/src/main/java/net/Indyuce/mmocore/skill/list/Ice_Spikes.java deleted file mode 100644 index a4834bea..00000000 --- a/src/main/java/net/Indyuce/mmocore/skill/list/Ice_Spikes.java +++ /dev/null @@ -1,77 +0,0 @@ -package net.Indyuce.mmocore.skill.list; - -import io.lumine.mythic.lib.damage.DamageType; -import io.lumine.mythic.lib.version.VersionMaterial; -import net.Indyuce.mmocore.MMOCore; -import net.Indyuce.mmocore.api.util.MMOCoreUtils; -import net.Indyuce.mmocore.api.util.math.Line3D; -import net.Indyuce.mmocore.api.util.math.formula.LinearValue; -import net.Indyuce.mmocore.skill.CasterMetadata; -import net.Indyuce.mmocore.skill.Skill; -import net.Indyuce.mmocore.skill.metadata.LocationSkillMetadata; -import net.Indyuce.mmocore.skill.metadata.SkillMetadata; -import org.bukkit.Location; -import org.bukkit.Particle; -import org.bukkit.Sound; -import org.bukkit.entity.Entity; -import org.bukkit.entity.LivingEntity; -import org.bukkit.potion.PotionEffect; -import org.bukkit.potion.PotionEffectType; -import org.bukkit.scheduler.BukkitRunnable; -import org.bukkit.util.Vector; - -public class Ice_Spikes extends Skill { - private static final double radius = 3; - - public Ice_Spikes() { - super(); - setMaterial(VersionMaterial.SNOWBALL.toMaterial()); - setLore("Ice spikes summon from the ground", "and shatter, each dealing &9{damage} &7damage", "to hit enemies and slowing them down", "for &9{slow} &7seconds.", "", "&e{cooldown}s Cooldown", "&9Costs {mana} {mana_name}"); - - addModifier("cooldown", new LinearValue(6, -.1, 2, 6)); - addModifier("mana", new LinearValue(20, 2)); - addModifier("damage", new LinearValue(3, 1)); - addModifier("slow", new LinearValue(4, 0)); - } - - @Override - public SkillMetadata whenCast(CasterMetadata caster, SkillInfo skill) { - LocationSkillMetadata cast = new LocationSkillMetadata(caster, skill, 20); - if (!cast.isSuccessful()) - return cast; - - Location loc = cast.getHit(); - double damage = cast.getModifier("damage"); - int slow = (int) (20 * cast.getModifier("slow")); - - new BukkitRunnable() { - int j = 0; - - @Override - public void run() { - - if (j++ > 8) { - cancel(); - return; - } - - Location loc1 = loc.clone().add(offset() * radius, 0, offset() * radius).add(0, 2, 0); - loc.getWorld().spawnParticle(Particle.FIREWORKS_SPARK, loc1, 32, 0, 2, 0, 0); - loc.getWorld().spawnParticle(Particle.SNOWBALL, loc1, 32, 0, 2, 0, 0); - loc.getWorld().playSound(loc1, Sound.BLOCK_GLASS_BREAK, 2, 0); - - Line3D line = new Line3D(loc.toVector(), loc.toVector().add(new Vector(0, 1, 0))); - for (Entity entity : MMOCoreUtils.getNearbyChunkEntities(loc1)) - if (line.distanceSquared(entity.getLocation().toVector()) < radius && Math.abs(entity.getLocation().getY() - loc1.getY()) < 10 && MMOCoreUtils.canTarget(caster.getPlayerData(), entity)) { - caster.attack((LivingEntity) entity, damage, DamageType.SKILL, DamageType.MAGIC); - ((LivingEntity) entity).addPotionEffect(new PotionEffect(PotionEffectType.SLOW, slow, 0)); - } - } - }.runTaskTimer(MMOCore.plugin, 0, 5); - return cast; - } - - private double offset() { - return random.nextDouble() * (random.nextBoolean() ? 1 : -1); - } -} diff --git a/src/main/java/net/Indyuce/mmocore/skill/list/Minor_Healings.java b/src/main/java/net/Indyuce/mmocore/skill/list/Minor_Healings.java deleted file mode 100644 index 4bfd9583..00000000 --- a/src/main/java/net/Indyuce/mmocore/skill/list/Minor_Healings.java +++ /dev/null @@ -1,42 +0,0 @@ -package net.Indyuce.mmocore.skill.list; - -import io.lumine.mythic.lib.comp.target.InteractionType; -import net.Indyuce.mmocore.api.util.math.formula.LinearValue; -import net.Indyuce.mmocore.api.util.math.particle.SmallParticleEffect; -import net.Indyuce.mmocore.skill.CasterMetadata; -import net.Indyuce.mmocore.skill.Skill; -import net.Indyuce.mmocore.skill.metadata.SkillMetadata; -import net.Indyuce.mmocore.skill.metadata.TargetSkillMetadata; -import org.bukkit.Material; -import org.bukkit.Particle; -import org.bukkit.Sound; -import org.bukkit.attribute.Attribute; -import org.bukkit.entity.LivingEntity; - -public class Minor_Healings extends Skill { - public Minor_Healings() { - super(); - setMaterial(Material.GOLDEN_APPLE); - setLore("Instantly grants &a{heal} &7HP to the", "target. Sneak to cast it on yourself.", "", "&e{cooldown}s Cooldown", "&9Costs {mana} {mana_name}"); - - addModifier("mana", new LinearValue(4, 2)); - addModifier("heal", new LinearValue(4, 2)); - addModifier("cooldown", new LinearValue(9, -.1, 1, 5)); - } - - @Override - public SkillMetadata whenCast(CasterMetadata caster, SkillInfo skill) { - SkillMetadata cast = caster.getPlayer().isSneaking() ? new SkillMetadata(caster, skill) : new TargetSkillMetadata(caster, skill, 50, InteractionType.SUPPORT_SKILL); - if (!cast.isSuccessful()) - return cast; - - LivingEntity target = cast instanceof TargetSkillMetadata ? ((TargetSkillMetadata) cast).getTarget() : caster.getPlayer(); - - double max = target.getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue(); - target.setHealth(Math.min(max, target.getHealth() + cast.getModifier("heal"))); - - new SmallParticleEffect(target, Particle.HEART, 1); - target.getWorld().playSound(target.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 2, 2); - return cast; - } -} diff --git a/src/main/java/net/Indyuce/mmocore/skill/list/Neptune_Gift.java b/src/main/java/net/Indyuce/mmocore/skill/list/Neptune_Gift.java index 0e36614a..89c084ee 100644 --- a/src/main/java/net/Indyuce/mmocore/skill/list/Neptune_Gift.java +++ b/src/main/java/net/Indyuce/mmocore/skill/list/Neptune_Gift.java @@ -1,40 +1,41 @@ package net.Indyuce.mmocore.skill.list; -import java.util.Optional; - -import net.Indyuce.mmocore.skill.PassiveSkill; -import org.bukkit.Bukkit; +import io.lumine.mythic.lib.skill.SkillMetadata; +import io.lumine.mythic.lib.skill.handler.SkillHandler; +import io.lumine.mythic.lib.skill.result.def.SimpleSkillResult; +import io.lumine.mythic.lib.skill.trigger.PassiveSkill; +import net.Indyuce.mmocore.api.event.PlayerResourceUpdateEvent; +import net.Indyuce.mmocore.api.player.PlayerData; import org.bukkit.Material; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; -import net.Indyuce.mmocore.MMOCore; -import net.Indyuce.mmocore.api.event.PlayerResourceUpdateEvent; -import net.Indyuce.mmocore.api.player.PlayerData; -import net.Indyuce.mmocore.skill.Skill; -import net.Indyuce.mmocore.api.util.math.formula.LinearValue; -import io.lumine.mythic.lib.version.VersionMaterial; +public class Neptune_Gift extends SkillHandler implements Listener { + public Neptune_Gift() { + super(false); -public class Neptune_Gift extends PassiveSkill { - public Neptune_Gift() { - super("NEPTUNE_GIFT"); - setName("Neptune's Gift"); + registerModifiers("extra"); + } - setMaterial(VersionMaterial.LILY_PAD.toMaterial()); - setLore("Resource regeneration is increased by &8{extra}% &7when standing in water."); - setPassive(); + @Override + public SimpleSkillResult getResult(SkillMetadata meta) { + throw new RuntimeException("Not supported"); + } - addModifier("extra", new LinearValue(30, 5)); + @Override + public void whenCast(SimpleSkillResult result, SkillMetadata skillMeta) { + throw new RuntimeException("Not supported"); + } - Bukkit.getPluginManager().registerEvents(this, MMOCore.plugin); - } + @EventHandler + public void a(PlayerResourceUpdateEvent event) { + PlayerData data = event.getData(); + if (event.getPlayer().getLocation().getBlock().getType() == Material.WATER) { + PassiveSkill skill = event.getData().getMMOPlayerData().getPassiveSkill(this); + if (skill == null) + return; - @EventHandler - public void a(PlayerResourceUpdateEvent event) { - PlayerData data = event.getData(); - if (event.getPlayer().getLocation().getBlock().getType() == Material.WATER) { - Optional skill = data.getProfess().findSkill(this); - skill.ifPresent(skillInfo -> event.setAmount(event.getAmount() * (1 + skillInfo.getModifier("extra", data.getSkillLevel(this)) / 100))); - } - } + event.setAmount(event.getAmount() * (1 + skill.getTriggeredSkill().getModifier("extra") / 100)); + } + } } diff --git a/src/main/java/net/Indyuce/mmocore/skill/list/Power_Mark.java b/src/main/java/net/Indyuce/mmocore/skill/list/Power_Mark.java deleted file mode 100644 index ec235df6..00000000 --- a/src/main/java/net/Indyuce/mmocore/skill/list/Power_Mark.java +++ /dev/null @@ -1,134 +0,0 @@ -package net.Indyuce.mmocore.skill.list; - -import io.lumine.mythic.lib.api.event.PlayerAttackEvent; -import io.lumine.mythic.lib.damage.DamageType; -import io.lumine.mythic.lib.version.VersionMaterial; -import io.lumine.mythic.lib.version.VersionSound; -import net.Indyuce.mmocore.MMOCore; -import net.Indyuce.mmocore.api.player.PlayerData; -import net.Indyuce.mmocore.api.util.MMOCoreUtils; -import net.Indyuce.mmocore.api.util.math.formula.LinearValue; -import net.Indyuce.mmocore.api.util.math.particle.ParabolicProjectile; -import net.Indyuce.mmocore.skill.CasterMetadata; -import net.Indyuce.mmocore.skill.PassiveSkill; -import net.Indyuce.mmocore.skill.metadata.SkillMetadata; -import org.bukkit.*; -import org.bukkit.entity.Entity; -import org.bukkit.entity.LivingEntity; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; -import org.bukkit.potion.PotionEffect; -import org.bukkit.potion.PotionEffectType; -import org.bukkit.scheduler.BukkitRunnable; -import org.bukkit.util.Vector; - -; - -public class Power_Mark extends PassiveSkill { - public Power_Mark() { - super(); - setMaterial(VersionMaterial.WITHER_SKELETON_SKULL.toMaterial()); - setLore("Attacking an enemy applies a deadly", "magical mark which spreads accross the", "ground. This mark accumulates &6{ratio}%", "of the damage dealt to the initial", "target over &6{duration} &7seconds.", "", "After this duration, the mark bursts, dealing", "accumulated damage to nearby enemies and", "stunning them for &6{stun}+ &7seconds.", "", "The more damage, the longer the stun.", "", "&e{cooldown}s Cooldown"); - setPassive(); - - addModifier("stun", new LinearValue(.4, .03)); - addModifier("ratio", new LinearValue(10, 5)); - addModifier("duration", new LinearValue(10, .1)); - addModifier("cooldown", new LinearValue(30, 0)); - - Bukkit.getPluginManager().registerEvents(this, MMOCore.plugin); - } - - @EventHandler - public void a(PlayerAttackEvent event) { - PlayerData data = PlayerData.get(event.getData().getUniqueId()); - if (!event.getAttack().getDamage().hasType(DamageType.WEAPON) || !data.getProfess().hasSkill(this)) - return; - - SkillMetadata cast = data.cast(this); - if (!cast.isSuccessful()) - return; - - new PowerMark(new CasterMetadata(data), cast, event.getEntity().getLocation()); - } - - public class PowerMark extends BukkitRunnable implements Listener { - private final CasterMetadata caster; - private final Location loc; - - private final double duration; - private final double ratio; - private double stun; - - private double accumulate; - private int j; - - public PowerMark(CasterMetadata caster, SkillMetadata cast, Location loc) { - this.caster = caster; - this.loc = loc; - - loc.getWorld().playSound(loc, Sound.BLOCK_END_PORTAL_FRAME_FILL, 2, 1); - - duration = cast.getModifier("duration"); - ratio = cast.getModifier("ratio") / 100; - stun = cast.getModifier("stun"); - - runTaskTimer(MMOCore.plugin, 0, 1); - Bukkit.getPluginManager().registerEvents(this, MMOCore.plugin); - } - - private void unregister() { - PlayerAttackEvent.getHandlerList().unregister(this); - cancel(); - } - - @EventHandler(priority = EventPriority.HIGHEST) - public void stackDamage(PlayerAttackEvent event) { - if (!event.isCancelled() && j < 20 * (duration - 2) && radiusCheck(event.getEntity().getLocation()) && event.getPlayer().equals(caster.getPlayer())) { - accumulate += event.getAttack().getDamage().getDamage() * ratio; - new ParabolicProjectile(event.getEntity().getLocation().add(0, event.getEntity().getHeight() / 2, 0), loc, () -> loc.getWorld().playSound(loc, Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1, 1), Color.PURPLE); - } - } - - private boolean radiusCheck(Location loc) { - return loc.getWorld().equals(this.loc.getWorld()) && loc.distanceSquared(this.loc) < 16; - } - - @Override - public void run() { - if (j++ > duration * 20) { - unregister(); - - for (double a = 0; a < Math.PI * 2; a += Math.PI * 2 / 17) - new ParabolicProjectile(loc, loc.clone().add(6 * Math.cos(a), 0, 6 * Math.sin(a)), Particle.SPELL_WITCH); - - loc.getWorld().playSound(loc, Sound.ENTITY_GENERIC_EXPLODE, 2, 0); - loc.getWorld().spawnParticle(Particle.EXPLOSION_LARGE, loc.clone().add(0, 1, 0), 16, 2, 2, 2, 0); - loc.getWorld().spawnParticle(Particle.EXPLOSION_NORMAL, loc.clone().add(0, 1, 0), 24, 0, 0, 0, .3f); - - stun += Math.log(Math.max(1, accumulate - 10)) / 8; - - for (Entity entity : MMOCoreUtils.getNearbyChunkEntities(loc)) - if (entity.getLocation().distanceSquared(loc) < 25 && MMOCoreUtils.canTarget(caster.getPlayerData(), entity)) { - ((LivingEntity) entity).addPotionEffect(new PotionEffect(PotionEffectType.SLOW, (int) (stun * 20), 10, false, false)); - caster.attack((LivingEntity) entity, accumulate, DamageType.SKILL, DamageType.MAGIC); - entity.setVelocity(format(entity.getLocation().subtract(loc).toVector().setY(0)).setY(.3)); - } - return; - } - - if (j % 2 == 0 && j > 20 * (duration - 2)) - loc.getWorld().playSound(loc, VersionSound.BLOCK_NOTE_BLOCK_PLING.toSound(), 1, (float) (1 + (j - 20 * (duration - 2)) / 40)); - - double a = (double) j / 16; - double r = Math.sqrt(Math.min(duration * 2 - (double) j / 10, 4)) * 2; - for (double k = 0; k < Math.PI * 2; k += Math.PI * 2 / 5) - loc.getWorld().spawnParticle(Particle.SPELL_WITCH, loc.clone().add(r * Math.cos(k + a), 0, r * Math.sin(k + a)), 0); - } - } - - private Vector format(Vector vec) { - return vec.length() < .01 ? new Vector(0, 0, 0) : vec.normalize(); - } -} diff --git a/src/main/java/net/Indyuce/mmocore/skill/list/Sneaky_Picky.java b/src/main/java/net/Indyuce/mmocore/skill/list/Sneaky_Picky.java index 96b33915..afde9eb3 100644 --- a/src/main/java/net/Indyuce/mmocore/skill/list/Sneaky_Picky.java +++ b/src/main/java/net/Indyuce/mmocore/skill/list/Sneaky_Picky.java @@ -1,48 +1,50 @@ package net.Indyuce.mmocore.skill.list; import io.lumine.mythic.lib.api.event.PlayerAttackEvent; +import io.lumine.mythic.lib.api.player.MMOPlayerData; import io.lumine.mythic.lib.damage.DamageType; -import net.Indyuce.mmocore.MMOCore; +import io.lumine.mythic.lib.skill.SkillMetadata; +import io.lumine.mythic.lib.skill.handler.SkillHandler; +import io.lumine.mythic.lib.skill.result.def.SimpleSkillResult; +import io.lumine.mythic.lib.skill.trigger.PassiveSkill; +import io.lumine.mythic.lib.skill.trigger.TriggerMetadata; import net.Indyuce.mmocore.api.player.PlayerData; -import net.Indyuce.mmocore.api.util.math.formula.LinearValue; -import net.Indyuce.mmocore.skill.PassiveSkill; -import net.Indyuce.mmocore.skill.metadata.SkillMetadata; -import org.bukkit.Bukkit; -import org.bukkit.Material; import org.bukkit.Particle; import org.bukkit.Sound; import org.bukkit.entity.LivingEntity; import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; -public class Sneaky_Picky extends PassiveSkill { +public class Sneaky_Picky extends SkillHandler implements Listener { public Sneaky_Picky() { - super(); - setMaterial(Material.DIAMOND_SWORD); - setLore("Your attack is empowered by &f{extra}% &7when", "delivering the first blow during a fight.", "", "&9Costs {mana} {mana_name}"); - setPassive(); + super(false); - addModifier("cooldown", new LinearValue(0, 0)); - addModifier("mana", new LinearValue(8, 1)); - addModifier("extra", new LinearValue(50, 20)); + registerModifiers("extra"); + } - Bukkit.getPluginManager().registerEvents(this, MMOCore.plugin); + @Override + public SimpleSkillResult getResult(SkillMetadata meta) { + return new SimpleSkillResult(meta.hasAttackBound() && meta.hasTargetEntity() && meta.getTargetEntityOrNull() instanceof LivingEntity); + } + + @Override + public void whenCast(SimpleSkillResult result, SkillMetadata skillMeta) { + LivingEntity target = (LivingEntity) skillMeta.getTargetEntity(); + skillMeta.getAttack().getDamage().multiply(1 + skillMeta.getModifier("extra") / 100, DamageType.WEAPON); + target.getWorld().spawnParticle(Particle.SMOKE_NORMAL, target.getLocation().add(0, target.getHeight() / 2, 0), 64, 0, 0, 0, .05); + target.getWorld().playSound(target.getLocation(), Sound.ENTITY_ZOMBIE_ATTACK_IRON_DOOR, 1, 2); } @EventHandler public void a(PlayerAttackEvent event) { - PlayerData data = PlayerData.get(event.getData().getUniqueId()); - if (!event.getAttack().getDamage().hasType(DamageType.WEAPON) || data.isInCombat() || !data.getProfess().hasSkill(this)) + MMOPlayerData data = event.getData(); + if (!event.getAttack().getDamage().hasType(DamageType.WEAPON) || PlayerData.get(data.getUniqueId()).isInCombat()) return; - SkillMetadata cast = data.cast(this); - if (!cast.isSuccessful()) + PassiveSkill skill = data.getPassiveSkill(this); + if (skill == null) return; - data.cast(cast.getInfo()); - - event.getAttack().getDamage().multiply(1 + cast.getModifier("extra") / 100, DamageType.WEAPON); - LivingEntity target = event.getEntity(); - target.getWorld().spawnParticle(Particle.SMOKE_NORMAL, target.getLocation().add(0, target.getHeight() / 2, 0), 64, 0, 0, 0, .05); - target.getWorld().playSound(target.getLocation(), Sound.ENTITY_ZOMBIE_ATTACK_IRON_DOOR, 1, 2); + skill.getTriggeredSkill().cast(new TriggerMetadata(event.getAttack(), event.getEntity())); } } diff --git a/src/main/java/net/Indyuce/mmocore/skill/list/Telekinesy.java b/src/main/java/net/Indyuce/mmocore/skill/list/Telekinesy.java deleted file mode 100644 index e88933c4..00000000 --- a/src/main/java/net/Indyuce/mmocore/skill/list/Telekinesy.java +++ /dev/null @@ -1,98 +0,0 @@ -package net.Indyuce.mmocore.skill.list; - -import io.lumine.mythic.lib.version.VersionMaterial; -import io.lumine.mythic.lib.version.VersionSound; -import net.Indyuce.mmocore.MMOCore; -import net.Indyuce.mmocore.api.player.PlayerData; -import net.Indyuce.mmocore.api.util.math.formula.LinearValue; -import net.Indyuce.mmocore.api.util.math.particle.ParabolicProjectile; -import net.Indyuce.mmocore.skill.CasterMetadata; -import net.Indyuce.mmocore.skill.Skill; -import net.Indyuce.mmocore.skill.metadata.SkillMetadata; -import net.Indyuce.mmocore.skill.metadata.TargetSkillMetadata; -import org.bukkit.Bukkit; -import org.bukkit.Location; -import org.bukkit.Particle; -import org.bukkit.Sound; -import org.bukkit.entity.Entity; -import org.bukkit.event.EventHandler; -import org.bukkit.event.HandlerList; -import org.bukkit.event.Listener; -import org.bukkit.event.player.PlayerInteractEvent; -import org.bukkit.scheduler.BukkitRunnable; - -public class Telekinesy extends Skill { - public Telekinesy() { - super(); - setMaterial(VersionMaterial.MAGENTA_DYE.toMaterial()); - setLore("You take the control over your target", "for &9{duration} &7seconds. Left click to throw him.", "Knockback force: &f{knockback}%", "", "&e{cooldown}s Cooldown", "&9Costs {mana} {mana_name}"); - - addModifier("cooldown", new LinearValue(20, -.3, 10, 20)); - addModifier("mana", new LinearValue(20, 2)); - addModifier("knockback", new LinearValue(50, 10)); - addModifier("duration", new LinearValue(3, .1, 3, 6)); - } - - @Override - public SkillMetadata whenCast(CasterMetadata caster, SkillInfo skill) { - TargetSkillMetadata cast = new TargetSkillMetadata(caster, skill, 7); - if (!cast.isSuccessful()) - return cast; - - caster.getPlayer().getWorld().playSound(caster.getPlayer().getLocation(), Sound.BLOCK_END_PORTAL_FRAME_FILL, 1, 1); - new TelekinesyRunnable(caster.getPlayerData(), cast.getTarget(), cast.getModifier("duration"), cast.getModifier("knockback") / 100); - return cast; - } - - public static class TelekinesyRunnable extends BukkitRunnable implements Listener { - private final Entity entity; - private final PlayerData data; - - private final long duration; - private final double d, f; - - private int j; - - public TelekinesyRunnable(PlayerData data, Entity entity, double duration, double force) { - this.entity = entity; - this.data = data; - - d = data.getPlayer().getLocation().distance(entity.getLocation()); - f = force; - this.duration = (long) (20 * duration); - - runTaskTimer(MMOCore.plugin, 0, 1); - Bukkit.getPluginManager().registerEvents(this, MMOCore.plugin); - } - - @EventHandler - public void a(PlayerInteractEvent event) { - if (event.getPlayer().equals(data.getPlayer()) && event.getAction().name().contains("LEFT_CLICK")) { - entity.setVelocity(data.getPlayer().getEyeLocation().getDirection().multiply(1.5 * f)); - entity.getWorld().playSound(entity.getLocation(), VersionSound.ENTITY_FIREWORK_ROCKET_BLAST.toSound(), 2, 1); - entity.getWorld().spawnParticle(Particle.SPELL_WITCH, entity.getLocation().add(0, entity.getHeight() / 2, 0), 16); - close(); - } - } - - @Override - public void run() { - if (!data.isOnline() || entity.isDead() || j++ >= duration) { - close(); - return; - } - - if (j % 8 == 0) - new ParabolicProjectile(data.getPlayer().getEyeLocation(), entity.getLocation().add(0, entity.getHeight() / 2, 0), Particle.SPELL_WITCH); - - Location loc = data.getPlayer().getEyeLocation().add(data.getPlayer().getEyeLocation().getDirection().multiply(d)); - entity.setVelocity(loc.subtract(entity.getLocation().add(0, entity.getHeight() / 2, 0)).toVector().multiply(2)); - entity.setFallDistance(0); - } - - private void close() { - cancel(); - HandlerList.unregisterAll(this); - } - } -} diff --git a/src/main/java/net/Indyuce/mmocore/skill/list/Warp.java b/src/main/java/net/Indyuce/mmocore/skill/list/Warp.java deleted file mode 100644 index fda98891..00000000 --- a/src/main/java/net/Indyuce/mmocore/skill/list/Warp.java +++ /dev/null @@ -1,59 +0,0 @@ -package net.Indyuce.mmocore.skill.list; - -import io.lumine.mythic.lib.version.VersionSound; -import net.Indyuce.mmocore.api.util.math.formula.LinearValue; -import net.Indyuce.mmocore.api.util.math.particle.ParabolicProjectile; -import net.Indyuce.mmocore.skill.CasterMetadata; -import net.Indyuce.mmocore.skill.Skill; -import net.Indyuce.mmocore.skill.metadata.SkillMetadata; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.Particle; -import org.bukkit.Sound; -import org.bukkit.block.Block; - -public class Warp extends Skill { - public Warp() { - super(); - setMaterial(Material.ENDER_PEARL); - setLore("Teleports you to target location.", "Max. Range: &5{range}", "", "&e{cooldown}s Cooldown", "&9Costs {mana} {mana_name}"); - - addModifier("cooldown", new LinearValue(15, -.3, 2, 15)); - addModifier("mana", new LinearValue(8, 3)); - addModifier("range", new LinearValue(16, 1, 0, 100)); - } - - @Override - public SkillMetadata whenCast(CasterMetadata caster, SkillInfo skill) { - WarpSkillMetadata cast = new WarpSkillMetadata(caster, skill); - if (!cast.isSuccessful()) - return cast; - - caster.getPlayer().getWorld().playSound(caster.getPlayer().getLocation(), Sound.BLOCK_END_PORTAL_FRAME_FILL, 1, 2); - - Location loc = cast.block.getLocation().add(0, 1, 0); - loc.setYaw(caster.getPlayer().getLocation().getYaw()); - loc.setPitch(caster.getPlayer().getLocation().getPitch()); - - new ParabolicProjectile(caster.getPlayer().getLocation().add(0, 1, 0), loc.clone().add(0, 1, 0), () -> { - if (caster.getPlayer().isOnline() && !caster.getPlayer().isDead()) { - caster.getPlayer().teleport(loc); - caster.getPlayer().getWorld().spawnParticle(Particle.EXPLOSION_LARGE, caster.getPlayer().getLocation().add(0, 1, 0), 0); - caster.getPlayer().getWorld().spawnParticle(Particle.SPELL_INSTANT, caster.getPlayer().getLocation().add(0, 1, 0), 32, 0, 0, 0, .1); - caster.getPlayer().getWorld().playSound(caster.getPlayer().getLocation(), VersionSound.ENTITY_ENDERMAN_TELEPORT.toSound(), 1, 1); - } - }, 2, Particle.SPELL_INSTANT); - return cast; - } - - private class WarpSkillMetadata extends SkillMetadata { - private Block block; - - public WarpSkillMetadata(CasterMetadata caster, SkillInfo skill) { - super(caster, skill); - - if (isSuccessful() && (block = caster.getPlayer().getTargetBlock(null, (int) getModifier("range"))) == null) - abort(); - } - } -} diff --git a/src/main/java/net/Indyuce/mmocore/skill/list/Weaken.java b/src/main/java/net/Indyuce/mmocore/skill/list/Weaken.java deleted file mode 100644 index 95688765..00000000 --- a/src/main/java/net/Indyuce/mmocore/skill/list/Weaken.java +++ /dev/null @@ -1,76 +0,0 @@ -package net.Indyuce.mmocore.skill.list; - -import io.lumine.mythic.lib.version.VersionMaterial; -import net.Indyuce.mmocore.MMOCore; -import net.Indyuce.mmocore.api.util.math.formula.LinearValue; -import net.Indyuce.mmocore.api.util.math.particle.ParabolicProjectile; -import net.Indyuce.mmocore.api.util.math.particle.SmallParticleEffect; -import net.Indyuce.mmocore.skill.CasterMetadata; -import net.Indyuce.mmocore.skill.Skill; -import net.Indyuce.mmocore.skill.metadata.SkillMetadata; -import net.Indyuce.mmocore.skill.metadata.TargetSkillMetadata; -import org.bukkit.Bukkit; -import org.bukkit.Particle; -import org.bukkit.entity.Entity; -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.entity.EntityDamageByEntityEvent; -import org.bukkit.util.Vector; - -public class Weaken extends Skill { - public Weaken() { - super(); - setMaterial(VersionMaterial.MAGENTA_DYE.toMaterial()); - setLore("The target is weakened for", "&8{duration} &7seconds and is dealt", "&7extra &8{ratio}% &7damage.", "", "&e{cooldown}s Cooldown", "&9Costs {mana} {mana_name}"); - - addModifier("cooldown", new LinearValue(20, -.1, 5, 20)); - addModifier("mana", new LinearValue(4, 1)); - addModifier("ratio", new LinearValue(30, 3)); - addModifier("duration", new LinearValue(10, -.1, 5, 10)); - } - - @Override - public SkillMetadata whenCast(CasterMetadata caster, SkillInfo skill) { - TargetSkillMetadata cast = new TargetSkillMetadata(caster, skill, 7); - if (!cast.isSuccessful()) - return cast; - - LivingEntity target = cast.getTarget(); - new ParabolicProjectile(caster.getPlayer().getLocation().add(0, 1, 0), target.getLocation().add(0, target.getHeight() / 2, 0), randomVector(caster.getPlayer()), () -> { - if (!target.isDead()) - new Weakened(target, cast.getModifier("ratio"), cast.getModifier("duration")); - }, 2, Particle.SPELL_WITCH); - return cast; - } - - private Vector randomVector(Player player) { - double a = Math.toRadians(player.getEyeLocation().getYaw() + 90); - a += (random.nextBoolean() ? 1 : -1) * (random.nextDouble() + .5) * Math.PI / 6; - return new Vector(Math.cos(a), .8, Math.sin(a)).normalize().multiply(.4); - } - - public static class Weakened implements Listener { - private final Entity entity; - private final double c; - - public Weakened(Entity entity, double ratio, double duration) { - this.entity = entity; - this.c = 1 + ratio / 100; - - new SmallParticleEffect(entity, Particle.SPELL_WITCH); - - Bukkit.getPluginManager().registerEvents(this, MMOCore.plugin); - Bukkit.getScheduler().scheduleSyncDelayedTask(MMOCore.plugin, () -> EntityDamageByEntityEvent.getHandlerList().unregister(this), (int) duration * 20); - } - - @EventHandler - public void a(EntityDamageByEntityEvent event) { - if (event.getEntity().equals(entity)) { - event.getEntity().getWorld().spawnParticle(Particle.SPELL_WITCH, entity.getLocation().add(0, entity.getHeight() / 2, 0), 16, .5, .5, .5, 0); - event.setDamage(event.getDamage() * c); - } - } - } -} diff --git a/src/main/java/net/Indyuce/mmocore/skill/metadata/LocationSkillMetadata.java b/src/main/java/net/Indyuce/mmocore/skill/metadata/LocationSkillMetadata.java deleted file mode 100644 index ca18b901..00000000 --- a/src/main/java/net/Indyuce/mmocore/skill/metadata/LocationSkillMetadata.java +++ /dev/null @@ -1,53 +0,0 @@ -package net.Indyuce.mmocore.skill.metadata; - -import io.lumine.mythic.lib.comp.target.InteractionType; -import net.Indyuce.mmocore.api.util.MMOCoreUtils; -import net.Indyuce.mmocore.skill.CasterMetadata; -import net.Indyuce.mmocore.skill.Skill.SkillInfo; -import org.bukkit.FluidCollisionMode; -import org.bukkit.Location; -import org.bukkit.util.RayTraceResult; - -public class LocationSkillMetadata extends SkillMetadata { - private Location loc; - - /** - * @param caster Player casting the skill - * @param skill Skill being cast - * @param range Skill raycast range - */ - public LocationSkillMetadata(CasterMetadata caster, SkillInfo skill, double range) { - this(caster, skill, range, InteractionType.OFFENSE_SKILL); - } - - /** - * @param caster Player casting the skill - * @param skill Skill being cast - * @param range Skill raycast range - * @param interaction If the skill is a friendly or offense skill. This determines if it - * can be cast on party members or not. - */ - public LocationSkillMetadata(CasterMetadata caster, SkillInfo skill, double range, InteractionType interaction) { - super(caster, skill); - - if (isSuccessful()) { - - RayTraceResult result = caster.getPlayer().getWorld().rayTrace(caster.getPlayer().getEyeLocation(), - caster.getPlayer().getEyeLocation().getDirection(), range, FluidCollisionMode.ALWAYS, true, 1.0D, - entity -> MMOCoreUtils.canTarget(caster.getPlayerData(), entity, interaction)); - if (result == null) - abort(CancelReason.OTHER); - else - loc = result.getHitBlock() != null ? result.getHitBlock().getLocation() - : result.getHitEntity() != null ? result.getHitEntity().getLocation() : null; - } - } - - public boolean hasHit() { - return loc != null; - } - - public Location getHit() { - return loc; - } -} diff --git a/src/main/java/net/Indyuce/mmocore/skill/metadata/SkillMetadata.java b/src/main/java/net/Indyuce/mmocore/skill/metadata/SkillMetadata.java deleted file mode 100644 index 6940220a..00000000 --- a/src/main/java/net/Indyuce/mmocore/skill/metadata/SkillMetadata.java +++ /dev/null @@ -1,127 +0,0 @@ -package net.Indyuce.mmocore.skill.metadata; - -import io.lumine.mythic.lib.MythicLib; -import io.lumine.mythic.lib.comp.flags.CustomFlag; -import io.lumine.mythic.lib.comp.mythicmobs.MythicSkillInfo; -import net.Indyuce.mmocore.api.player.PlayerData; -import net.Indyuce.mmocore.skill.CasterMetadata; -import net.Indyuce.mmocore.skill.Skill; -import net.Indyuce.mmocore.skill.Skill.SkillInfo; - -import java.util.Objects; - -public class SkillMetadata implements MythicSkillInfo { - private final SkillInfo skill; - private final int level; - private final double mana, cooldown, stamina; - - private CancelReason cancelReason; - - public SkillMetadata(CasterMetadata caster, SkillInfo skill) { - this.skill = skill; - - PlayerData data = caster.getPlayerData(); - - level = data.getSkillLevel(skill.getSkill()); - cooldown = skill.getSkill().hasModifier("cooldown") ? getModifier("cooldown") : 0; - mana = skill.getSkill().hasModifier("mana") ? getModifier("mana") : 0; - stamina = skill.getSkill().hasModifier("stamina") ? getModifier("stamina") : 0; - cancelReason = !data.hasSkillUnlocked(skill) ? CancelReason.LOCKED - : data.getCooldownMap().isOnCooldown(getSkill()) ? CancelReason.COOLDOWN - : mana > data.getMana() ? CancelReason.MANA - : stamina > data.getStamina() ? CancelReason.STAMINA - : !data.isOnline() ? CancelReason.OTHER - : !MythicLib.plugin.getFlags().isFlagAllowed(data.getPlayer(), CustomFlag.MMO_ABILITIES) ? CancelReason.FLAG - : null; - } - - public SkillMetadata(PlayerData data, SkillInfo skill, CancelReason reason) { - this.skill = skill; - this.cancelReason = reason; - - level = data.getSkillLevel(skill.getSkill()); - cooldown = skill.getSkill().hasModifier("cooldown") ? getModifier("cooldown") : 0; - mana = skill.getSkill().hasModifier("mana") ? getModifier("mana") : 0; - stamina = skill.getSkill().hasModifier("stamina") ? getModifier("stamina") : 0; - } - - public Skill getSkill() { - return skill.getSkill(); - } - - public SkillInfo getInfo() { - return skill; - } - - public int getLevel() { - return level; - } - - public double getStaminaCost() { - return stamina; - } - - public double getManaCost() { - return mana; - } - - public double getCooldown() { - return cooldown; - } - - public boolean isSuccessful() { - return cancelReason == null; - } - - public CancelReason getCancelReason() { - return cancelReason; - } - - public void abort() { - abort(CancelReason.OTHER); - } - - public void abort(CancelReason reason) { - cancelReason = Objects.requireNonNull(reason, "Reason cannot be null"); - } - - @Override - public double getModifier(String modifier) { - return skill.getModifier(modifier, level); - } - - public enum CancelReason { - - /** - * Flag plugin like WorldGuard or any other - */ - FLAG, - - /** - * Not enough stamina - */ - MANA, - - /** - * Not enough mana - */ - STAMINA, - - /** - * Skill still on cooldown - */ - COOLDOWN, - - /** - * Skill is locked - */ - LOCKED, - - /** - * Anything else, used for instance when MythicMobs - * skill conditions prevent the skill from casting or - * when the Bukkit pre cast event is cancelled - */ - OTHER; - } -} diff --git a/src/main/java/net/Indyuce/mmocore/skill/metadata/TargetSkillMetadata.java b/src/main/java/net/Indyuce/mmocore/skill/metadata/TargetSkillMetadata.java deleted file mode 100644 index 934b2033..00000000 --- a/src/main/java/net/Indyuce/mmocore/skill/metadata/TargetSkillMetadata.java +++ /dev/null @@ -1,45 +0,0 @@ -package net.Indyuce.mmocore.skill.metadata; - -import io.lumine.mythic.lib.MythicLib; -import io.lumine.mythic.lib.api.MMORayTraceResult; -import io.lumine.mythic.lib.comp.target.InteractionType; -import net.Indyuce.mmocore.api.util.MMOCoreUtils; -import net.Indyuce.mmocore.skill.CasterMetadata; -import net.Indyuce.mmocore.skill.Skill.SkillInfo; -import org.bukkit.entity.LivingEntity; - -public class TargetSkillMetadata extends SkillMetadata { - private LivingEntity target; - - /** - * @param caster Player casting the skill - * @param skill Skill being cast - * @param range Skill raycast range - */ - public TargetSkillMetadata(CasterMetadata caster, SkillInfo skill, double range) { - this(caster, skill, range, InteractionType.OFFENSE_SKILL); - } - - /** - * @param caster Player casting the skill - * @param skill Skill being cast - * @param range Skill raycast range - * @param interaction If the skill is a friendly or offense skill. This determines if it - * can be cast on party members or not. - */ - public TargetSkillMetadata(CasterMetadata caster, SkillInfo skill, double range, InteractionType interaction) { - super(caster, skill); - - if (isSuccessful()) { - MMORayTraceResult result = MythicLib.plugin.getVersion().getWrapper().rayTrace(caster.getPlayer(), range, entity -> MMOCoreUtils.canTarget(caster.getPlayerData(), entity, interaction)); - if (!result.hasHit()) - abort(); - else - target = result.getHit(); - } - } - - public LivingEntity getTarget() { - return target; - } -} diff --git a/src/main/resources/default/skills/ambers.yml b/src/main/resources/default/skills/ambers.yml new file mode 100644 index 00000000..24eab92a --- /dev/null +++ b/src/main/resources/default/skills/ambers.yml @@ -0,0 +1,33 @@ +name: Ambers +lore: +- Dealing magic damage has &630% &7chance +- of dropping an amber on the ground. +- '' +- When picked up, ambers stack and +- refund &9{percent}% &7of your missing mana. +- '' +- '&oAmbers can be used in other damaging skills.' +- '&oThe more you collect, the more powerful the skills.' +- '' +- '&e{cooldown}s Cooldown' +material: EMERALD +mana: + base: 0.0 + per-level: 0.0 + max: 0.0 + min: 0.0 +stamina: + base: 0.0 + per-level: 0.0 + max: 0.0 + min: 0.0 +cooldown: + base: 3.0 + per-level: -0.1 + max: 3.0 + min: 1.0 +percent: + base: 10.0 + per-level: 0.1 + max: 20.0 + min: 10.0 diff --git a/src/main/resources/default/skills/backstab.yml b/src/main/resources/default/skills/backstab.yml new file mode 100644 index 00000000..f8a6704b --- /dev/null +++ b/src/main/resources/default/skills/backstab.yml @@ -0,0 +1,20 @@ +name: Backstab +lore: +- Backstabs deal &c{extra}%&7 damage. +- '' +- '&9Costs {mana} {mana_name}' +material: FLINT +mana: + base: 8.0 + per-level: 1.0 +stamina: + base: 0.0 + per-level: 0.0 + max: 0.0 + min: 0.0 +extra: + base: 50.0 + per-level: 20.0 +cooldown: + base: 0.0 + per-level: 0.0 diff --git a/src/main/resources/default/skills/combo-attack.yml b/src/main/resources/default/skills/combo-attack.yml new file mode 100644 index 00000000..fb8b986f --- /dev/null +++ b/src/main/resources/default/skills/combo-attack.yml @@ -0,0 +1,29 @@ +name: Combo Attack +lore: +- Violenty slashes your target &8{count} +- times for a total of &8{damage} &7damage. +- '' +- '&e{cooldown}s Cooldown' +- '&9Costs {mana} {mana_name}' +material: IRON_SWORD +damage: + base: 9.0 + per-level: 0.3 +mana: + base: 10.0 + per-level: -0.1 + max: 5.0 + min: 3.0 +stamina: + base: 0.0 + per-level: 0.0 + max: 0.0 + min: 0.0 +cooldown: + base: 20.0 + per-level: -0.1 + max: 20.0 + min: 5.0 +count: + base: 3.0 + per-level: 0.2 diff --git a/src/main/resources/default/skills/control.yml b/src/main/resources/default/skills/control.yml new file mode 100644 index 00000000..d674a4d8 --- /dev/null +++ b/src/main/resources/default/skills/control.yml @@ -0,0 +1,29 @@ +name: Control +lore: +- Your target is temporarily slowed for &8{duration} &7seconds. +- As soon as you left click, it gets +- pushed back where you are looking at. +- 'Knockback force: &f{knockback}%' +- '' +- '&e{cooldown}s Cooldown' +- '&9Costs {mana} {mana_name}' +material: MAGENTA_DYE +duration: + base: 2.0 + per-level: 0.0 +mana: + base: 15.0 + per-level: 1.5 +stamina: + base: 0.0 + per-level: 0.0 + max: 0.0 + min: 0.0 +cooldown: + base: 18.0 + per-level: -0.3 + max: 20.0 + min: 10.0 +knockback: + base: 30.0 + per-level: 3.0 diff --git a/src/main/resources/default/skills/deep-wound.yml b/src/main/resources/default/skills/deep-wound.yml new file mode 100644 index 00000000..bbb31d69 --- /dev/null +++ b/src/main/resources/default/skills/deep-wound.yml @@ -0,0 +1,28 @@ +name: Deep Wound +lore: +- You puncture your target, dealing &c{damage} &7damage. +- Damage is increased up to &c+{extra}% &7based +- on your target's missing health. +- '' +- '&e{cooldown}s Cooldown' +- '&9Costs {mana} {mana_name}' +material: REDSTONE +damage: + base: 5.0 + per-level: 1.5 +mana: + base: 8.0 + per-level: 3.0 +stamina: + base: 0.0 + per-level: 0.0 + max: 0.0 + min: 0.0 +extra: + base: 50.0 + per-level: 20.0 +cooldown: + base: 20.0 + per-level: -0.1 + max: 20.0 + min: 5.0 diff --git a/src/main/resources/default/skills/empowered-attack.yml b/src/main/resources/default/skills/empowered-attack.yml new file mode 100644 index 00000000..05c1173b --- /dev/null +++ b/src/main/resources/default/skills/empowered-attack.yml @@ -0,0 +1,34 @@ +name: Empowered Attack +lore: +- You charge your weapon with lightning. +- Your next attack deals &f{extra}% &7extra damage +- and spreads to enemies within &f{radius} &7blocks +- for &f{ratio}% &7of the initial damage. +- '' +- '&e{cooldown}s Cooldown' +- '&9Costs {mana} {mana_name}' +material: BONE_MEAL +mana: + base: 4.0 + per-level: 1.0 +stamina: + base: 0.0 + per-level: 0.0 + max: 0.0 + min: 0.0 +extra: + base: 30.0 + per-level: 8.0 +cooldown: + base: 10.0 + per-level: -0.2 + max: 10.0 + min: 5.0 +radius: + base: 4.0 + per-level: 0.0 +ratio: + base: 30.0 + per-level: 10.0 + max: 100.0 + min: 30.0 diff --git a/src/main/resources/default/skills/evade.yml b/src/main/resources/default/skills/evade.yml new file mode 100644 index 00000000..3be455a1 --- /dev/null +++ b/src/main/resources/default/skills/evade.yml @@ -0,0 +1,24 @@ +name: Evade +lore: +- You become imune to damage for &8{duration} &7seconds. +- Cancels when dealing weapon damage. +- '' +- '&e{cooldown}s Cooldown' +- '&9Costs {mana} {mana_name}' +material: LEATHER_BOOTS +duration: + base: 2.0 + per-level: 0.3 + max: 10.0 + min: 2.0 +mana: + base: 8.0 + per-level: 3.0 +stamina: + base: 0.0 + per-level: 0.0 + max: 0.0 + min: 0.0 +cooldown: + base: 20.0 + per-level: 0.0 diff --git a/src/main/resources/default/skills/fire-berserker.yml b/src/main/resources/default/skills/fire-berserker.yml new file mode 100644 index 00000000..f5cf6db3 --- /dev/null +++ b/src/main/resources/default/skills/fire-berserker.yml @@ -0,0 +1,17 @@ +name: Fire Berserker +lore: +- You deal &c{extra}% &7more damage when on fire. +material: FLINT_AND_STEEL +mana: + base: 0.0 + per-level: 0.0 + max: 0.0 + min: 0.0 +stamina: + base: 0.0 + per-level: 0.0 + max: 0.0 + min: 0.0 +extra: + base: 10.0 + per-level: 5.0 diff --git a/src/main/resources/default/skills/fire-rage.yml b/src/main/resources/default/skills/fire-rage.yml new file mode 100644 index 00000000..b45746e4 --- /dev/null +++ b/src/main/resources/default/skills/fire-rage.yml @@ -0,0 +1,35 @@ +name: Fire Rage +lore: +- For {duration} seconds, you slow down and are able +- to cast up to {count} fireballs by left clicking. +- '' +- Fireballs deal &c{damage} &7damage upon contact +- and ignite your target for &c{ignite} &7seconds. +- '&e{cooldown}s Cooldown' +- '&9Costs {mana} {mana_name}' +material: FIRE_CHARGE +duration: + base: 8.0 + per-level: 0.0 +damage: + base: 5.0 + per-level: 3.0 +ignite: + base: 2.0 + per-level: 0.1 +mana: + base: 15.0 + per-level: 1.0 +stamina: + base: 0.0 + per-level: 0.0 + max: 0.0 + min: 0.0 +count: + base: 4.0 + per-level: 0.0 +cooldown: + base: 9.0 + per-level: -0.1 + max: 5.0 + min: 1.0 diff --git a/src/main/resources/default/skills/fire-storm.yml b/src/main/resources/default/skills/fire-storm.yml new file mode 100644 index 00000000..57f4fc02 --- /dev/null +++ b/src/main/resources/default/skills/fire-storm.yml @@ -0,0 +1,29 @@ +name: Fire Storm +lore: +- Casts a flurry of 6 fire projectiles onto +- nearby enemies, proritizing the initial +- target. Each projectile deals &c{damage} &7damage +- and ignite the target for &c{ignite} &7seconds. +- '' +- '&e{cooldown}s Cooldown' +- '&9Costs {mana} {mana_name}' +material: BLAZE_POWDER +damage: + base: 5.0 + per-level: 3.0 +ignite: + base: 2.0 + per-level: 0.1 +mana: + base: 15.0 + per-level: 2.0 +stamina: + base: 0.0 + per-level: 0.0 + max: 0.0 + min: 0.0 +cooldown: + base: 5.0 + per-level: -0.1 + max: 5.0 + min: 1.0 diff --git a/src/main/resources/default/skills/fireball.yml b/src/main/resources/default/skills/fireball.yml new file mode 100644 index 00000000..faec3105 --- /dev/null +++ b/src/main/resources/default/skills/fireball.yml @@ -0,0 +1,35 @@ +name: Fireball +lore: +- Casts a deadly fireball onto your +- target, dealing &c{damage} &7damage upon contact +- and igniting it for &c{ignite} &7seconds. +- '' +- Shatters into 3 blazing hot shards which stick +- to walls and explode 3 seconds later, dealing +- '&c{ratio}% &7of the initial spell damage.' +- '' +- '&e{cooldown}s Cooldown' +- '&9Costs {mana} {mana_name}' +material: FIRE_CHARGE +damage: + base: 5.0 + per-level: 3.0 +ignite: + base: 2.0 + per-level: 0.1 +mana: + base: 15.0 + per-level: 1.0 +stamina: + base: 0.0 + per-level: 0.0 + max: 0.0 + min: 0.0 +cooldown: + base: 9.0 + per-level: -0.1 + max: 5.0 + min: 1.0 +ratio: + base: 50.0 + per-level: 3.0 diff --git a/src/main/resources/default/skills/furtive-strike.yml b/src/main/resources/default/skills/furtive-strike.yml new file mode 100644 index 00000000..ef1fd5e6 --- /dev/null +++ b/src/main/resources/default/skills/furtive-strike.yml @@ -0,0 +1,30 @@ +name: Furtive Strike +lore: +- Deals &c{damage} &7damage, increased by &c{extra}% &7if +- there are not any enemies within &c{radius} &7blocks. +- '' +- '&e{cooldown}s Cooldown' +- '&9Costs {mana} {mana_name}' +material: COAL +damage: + base: 5.0 + per-level: 1.5 +mana: + base: 8.0 + per-level: 3.0 +stamina: + base: 0.0 + per-level: 0.0 + max: 0.0 + min: 0.0 +extra: + base: 50.0 + per-level: 20.0 +cooldown: + base: 20.0 + per-level: -0.1 + max: 20.0 + min: 5.0 +radius: + base: 7.0 + per-level: 0.0 diff --git a/src/main/resources/default/skills/greater-healings.yml b/src/main/resources/default/skills/greater-healings.yml new file mode 100644 index 00000000..38fc7fe3 --- /dev/null +++ b/src/main/resources/default/skills/greater-healings.yml @@ -0,0 +1,24 @@ +name: Greater Healings +lore: +- Instantly grants &a{heal} &7HP to the +- target. Sneak to cast it on yourself. +- '' +- '&e{cooldown}s Cooldown' +- '&9Costs {mana} {mana_name}' +material: GOLDEN_APPLE +mana: + base: 4.0 + per-level: 2.0 +stamina: + base: 0.0 + per-level: 0.0 + max: 0.0 + min: 0.0 +heal: + base: 10.0 + per-level: 4.0 +cooldown: + base: 9.0 + per-level: -0.1 + max: 5.0 + min: 1.0 diff --git a/src/main/resources/default/skills/human-shield.yml b/src/main/resources/default/skills/human-shield.yml new file mode 100644 index 00000000..4c1bd8cf --- /dev/null +++ b/src/main/resources/default/skills/human-shield.yml @@ -0,0 +1,40 @@ +name: Human Shield +lore: +- Casts a protection charm onto target ally, +- reducing damage taken by &a{reduction}%&7. +- '&a{redirect}% &7of this damage is redirected to you.' +- Charm is cancelled when reaching &c{low}%&7 health. +- Lasts &a{duration} &7seconds. +- '' +- '&e{cooldown}s Cooldown' +- '&9Costs {mana} {mana_name}' +material: TOTEM_OF_UNDYING +redirect: + base: 30.0 + per-level: -2.0 + max: 30.0 + min: 20.0 +duration: + base: 7.0 + per-level: 0.0 +mana: + base: 15.0 + per-level: 1.5 +low: + base: 10.0 + per-level: 0.0 +stamina: + base: 0.0 + per-level: 0.0 + max: 0.0 + min: 0.0 +cooldown: + base: 18.0 + per-level: -0.3 + max: 18.0 + min: 14.0 +reduction: + base: 30.0 + per-level: 3.0 + max: 70.0 + min: 30.0 diff --git a/src/main/resources/default/skills/ice-spikes.yml b/src/main/resources/default/skills/ice-spikes.yml new file mode 100644 index 00000000..c366f960 --- /dev/null +++ b/src/main/resources/default/skills/ice-spikes.yml @@ -0,0 +1,29 @@ +name: Ice Spikes +lore: +- Ice spikes summon from the ground +- and shatter, each dealing &9{damage} &7damage +- to hit enemies and slowing them down +- for &9{slow} &7seconds. +- '' +- '&e{cooldown}s Cooldown' +- '&9Costs {mana} {mana_name}' +material: SNOWBALL +damage: + base: 3.0 + per-level: 1.0 +mana: + base: 20.0 + per-level: 2.0 +slow: + base: 4.0 + per-level: 0.0 +stamina: + base: 0.0 + per-level: 0.0 + max: 0.0 + min: 0.0 +cooldown: + base: 6.0 + per-level: -0.1 + max: 6.0 + min: 2.0 diff --git a/src/main/resources/default/skills/minor-healings.yml b/src/main/resources/default/skills/minor-healings.yml new file mode 100644 index 00000000..42c13963 --- /dev/null +++ b/src/main/resources/default/skills/minor-healings.yml @@ -0,0 +1,24 @@ +name: Minor Healings +lore: +- Instantly grants &a{heal} &7HP to the +- target. Sneak to cast it on yourself. +- '' +- '&e{cooldown}s Cooldown' +- '&9Costs {mana} {mana_name}' +material: GOLDEN_APPLE +mana: + base: 4.0 + per-level: 2.0 +stamina: + base: 0.0 + per-level: 0.0 + max: 0.0 + min: 0.0 +heal: + base: 4.0 + per-level: 2.0 +cooldown: + base: 9.0 + per-level: -0.1 + max: 5.0 + min: 1.0 diff --git a/src/main/resources/default/skills/neptune-gift.yml b/src/main/resources/default/skills/neptune-gift.yml new file mode 100644 index 00000000..e664b23b --- /dev/null +++ b/src/main/resources/default/skills/neptune-gift.yml @@ -0,0 +1,7 @@ +name: Neptune's Gift +lore: +- Resource regeneration is increased by &8{extra}% &7when standing in water. +material: LILY_PAD +extra: + base: 30.0 + per-level: 5.0 diff --git a/src/main/resources/default/skills/power-mark.yml b/src/main/resources/default/skills/power-mark.yml new file mode 100644 index 00000000..5ab415fe --- /dev/null +++ b/src/main/resources/default/skills/power-mark.yml @@ -0,0 +1,38 @@ +name: Power Mark +lore: +- Attacking an enemy applies a deadly +- magical mark which spreads accross the +- ground. This mark accumulates &6{ratio}% +- of the damage dealt to the initial +- target over &6{duration} &7seconds. +- '' +- After this duration, the mark bursts, dealing +- accumulated damage to nearby enemies and +- stunning them for &6{stun}+ &7seconds. +- '' +- The more damage, the longer the stun. +- '' +- '&e{cooldown}s Cooldown' +material: WITHER_SKELETON_SKULL +duration: + base: 10.0 + per-level: 0.1 +mana: + base: 0.0 + per-level: 0.0 + max: 0.0 + min: 0.0 +stamina: + base: 0.0 + per-level: 0.0 + max: 0.0 + min: 0.0 +cooldown: + base: 30.0 + per-level: 0.0 +stun: + base: 0.4 + per-level: 0.03 +ratio: + base: 10.0 + per-level: 5.0 diff --git a/src/main/resources/default/skills/sneaky-picky.yml b/src/main/resources/default/skills/sneaky-picky.yml new file mode 100644 index 00000000..db00a5f1 --- /dev/null +++ b/src/main/resources/default/skills/sneaky-picky.yml @@ -0,0 +1,21 @@ +name: Sneaky Picky +lore: +- Your attack is empowered by &f{extra}% &7when +- delivering the first blow during a fight. +- '' +- '&9Costs {mana} {mana_name}' +material: DIAMOND_SWORD +mana: + base: 8.0 + per-level: 1.0 +stamina: + base: 0.0 + per-level: 0.0 + max: 0.0 + min: 0.0 +extra: + base: 50.0 + per-level: 20.0 +cooldown: + base: 0.0 + per-level: 0.0 diff --git a/src/main/resources/default/skills/telekinesy.yml b/src/main/resources/default/skills/telekinesy.yml new file mode 100644 index 00000000..f965da4e --- /dev/null +++ b/src/main/resources/default/skills/telekinesy.yml @@ -0,0 +1,30 @@ +name: Telekinesy +lore: +- You take the control over your target +- for &9{duration} &7seconds. Left click to throw him. +- 'Knockback force: &f{knockback}%' +- '' +- '&e{cooldown}s Cooldown' +- '&9Costs {mana} {mana_name}' +material: MAGENTA_DYE +duration: + base: 3.0 + per-level: 0.1 + max: 6.0 + min: 3.0 +mana: + base: 20.0 + per-level: 2.0 +stamina: + base: 0.0 + per-level: 0.0 + max: 0.0 + min: 0.0 +cooldown: + base: 20.0 + per-level: -0.3 + max: 20.0 + min: 10.0 +knockback: + base: 50.0 + per-level: 10.0 diff --git a/src/main/resources/default/skills/warp.yml b/src/main/resources/default/skills/warp.yml new file mode 100644 index 00000000..9a98be5b --- /dev/null +++ b/src/main/resources/default/skills/warp.yml @@ -0,0 +1,26 @@ +name: Warp +lore: +- Teleports you to target location. +- 'Max. Range: &5{range}' +- '' +- '&e{cooldown}s Cooldown' +- '&9Costs {mana} {mana_name}' +material: ENDER_PEARL +mana: + base: 8.0 + per-level: 3.0 +stamina: + base: 0.0 + per-level: 0.0 + max: 0.0 + min: 0.0 +cooldown: + base: 15.0 + per-level: -0.3 + max: 15.0 + min: 2.0 +range: + base: 16.0 + per-level: 1.0 + max: 100.0 + min: 0.0 diff --git a/src/main/resources/default/skills/weaken.yml b/src/main/resources/default/skills/weaken.yml new file mode 100644 index 00000000..ad80071e --- /dev/null +++ b/src/main/resources/default/skills/weaken.yml @@ -0,0 +1,30 @@ +name: Weaken +lore: +- The target is weakened for +- '&8{duration} &7seconds and is dealt' +- '&7extra &8{ratio}% &7damage.' +- '' +- '&e{cooldown}s Cooldown' +- '&9Costs {mana} {mana_name}' +material: MAGENTA_DYE +duration: + base: 10.0 + per-level: -0.1 + max: 10.0 + min: 5.0 +mana: + base: 4.0 + per-level: 1.0 +stamina: + base: 0.0 + per-level: 0.0 + max: 0.0 + min: 0.0 +cooldown: + base: 20.0 + per-level: -0.1 + max: 20.0 + min: 5.0 +ratio: + base: 30.0 + per-level: 3.0