diff --git a/pom.xml b/pom.xml index d4d0c1a6..078f2afc 100644 --- a/pom.xml +++ b/pom.xml @@ -131,7 +131,7 @@ io.lumine MythicLib - 1.1.0 + 1.1.2 provided diff --git a/src/main/java/net/Indyuce/mmocore/MMOCore.java b/src/main/java/net/Indyuce/mmocore/MMOCore.java index 8ad97c99..d9f29bdc 100644 --- a/src/main/java/net/Indyuce/mmocore/MMOCore.java +++ b/src/main/java/net/Indyuce/mmocore/MMOCore.java @@ -32,10 +32,7 @@ import net.Indyuce.mmocore.comp.region.WorldGuardRegionHandler; import net.Indyuce.mmocore.comp.vault.VaultEconomy; import net.Indyuce.mmocore.comp.vault.VaultMMOLoader; import net.Indyuce.mmocore.listener.*; -import net.Indyuce.mmocore.listener.option.DeathExperienceLoss; -import net.Indyuce.mmocore.listener.option.NoSpawnerEXP; -import net.Indyuce.mmocore.listener.option.RedirectVanillaExp; -import net.Indyuce.mmocore.listener.option.VanillaExperienceOverride; +import net.Indyuce.mmocore.listener.option.*; import net.Indyuce.mmocore.listener.profession.FishingListener; import net.Indyuce.mmocore.listener.profession.PlayerCollectStats; import net.Indyuce.mmocore.manager.ExperienceManager; @@ -232,6 +229,9 @@ public class MMOCore extends LuminePlugin { if (getConfig().getBoolean("death-exp-loss.enabled")) Bukkit.getPluginManager().registerEvents(new DeathExperienceLoss(), this); + if (getConfig().getBoolean("shift-click-player-profile-check")) + Bukkit.getPluginManager().registerEvents(new PlayerProfileCheck(), this); + Bukkit.getPluginManager().registerEvents(new WaypointsListener(), this); Bukkit.getPluginManager().registerEvents(new PlayerListener(), this); Bukkit.getPluginManager().registerEvents(new GoldPouchesListener(), this); diff --git a/src/main/java/net/Indyuce/mmocore/api/event/CustomBlockMineEvent.java b/src/main/java/net/Indyuce/mmocore/api/event/CustomBlockMineEvent.java index 76d8dcb6..f4f02577 100644 --- a/src/main/java/net/Indyuce/mmocore/api/event/CustomBlockMineEvent.java +++ b/src/main/java/net/Indyuce/mmocore/api/event/CustomBlockMineEvent.java @@ -1,78 +1,60 @@ package net.Indyuce.mmocore.api.event; -import java.util.ArrayList; -import java.util.List; - +import net.Indyuce.mmocore.api.block.BlockInfo; +import net.Indyuce.mmocore.api.player.PlayerData; import org.bukkit.block.Block; import org.bukkit.event.Cancellable; import org.bukkit.event.HandlerList; import org.bukkit.inventory.ItemStack; -import net.Indyuce.mmocore.api.block.BlockInfo; -import net.Indyuce.mmocore.api.droptable.condition.ConditionInstance; -import net.Indyuce.mmocore.api.loot.LootBuilder; -import net.Indyuce.mmocore.api.player.PlayerData; +import java.util.List; public class CustomBlockMineEvent extends PlayerDataEvent implements Cancellable { - private static final HandlerList handlers = new HandlerList(); + private static final HandlerList handlers = new HandlerList(); - private final Block block; - private final BlockInfo info; - private final List drops; + private final Block block; + private final BlockInfo info; + private final List drops; - @Deprecated - private boolean canBreak; - private boolean cancelled = false; + private boolean cancelled; - public CustomBlockMineEvent(PlayerData player, Block block, BlockInfo info, boolean canBreak) { - super(player); + public CustomBlockMineEvent(PlayerData player, Block block, BlockInfo info, List drops, boolean cancelled) { + super(player); - this.block = block; - this.info = info; - this.drops = (info.hasDropTable() && player.isOnline() && info.getDropTable().areConditionsMet(new ConditionInstance(player.getPlayer()))) - ? info.collectDrops(new LootBuilder(player, 0)) - : new ArrayList<>(); - this.canBreak = canBreak; - } + this.block = block; + this.info = info; + this.drops = drops; + this.cancelled = cancelled; + } - public Block getBlock() { - return block; - } + public Block getBlock() { + return block; + } - public List getDrops() { - return drops; - } + public List getDrops() { + return drops; + } - public BlockInfo getBlockInfo() { - return info; - } + public BlockInfo getBlockInfo() { + return info; + } - @Deprecated - public boolean canBreak() { - return canBreak; - } + @Override + public boolean isCancelled() { + return cancelled; + } - @Deprecated - public void setCanBreak(boolean value) { - canBreak = value; - } + @Override + public void setCancelled(boolean value) { + cancelled = value; + } - @Override - public boolean isCancelled() { - return cancelled; - } + @Override + public HandlerList getHandlers() { + return handlers; + } - @Override - public void setCancelled(boolean value) { - cancelled = value; - } - - @Override - public HandlerList getHandlers() { - return handlers; - } - - public static HandlerList getHandlerList() { - return handlers; - } + public static HandlerList getHandlerList() { + return handlers; + } } diff --git a/src/main/java/net/Indyuce/mmocore/api/event/PlayerPostCastSkillEvent.java b/src/main/java/net/Indyuce/mmocore/api/event/PlayerPostCastSkillEvent.java index 8270e463..8f3147bd 100644 --- a/src/main/java/net/Indyuce/mmocore/api/event/PlayerPostCastSkillEvent.java +++ b/src/main/java/net/Indyuce/mmocore/api/event/PlayerPostCastSkillEvent.java @@ -1,15 +1,15 @@ package net.Indyuce.mmocore.api.event; import net.Indyuce.mmocore.api.player.PlayerData; -import net.Indyuce.mmocore.api.skill.Skill.SkillInfo; -import net.Indyuce.mmocore.api.skill.SkillResult; +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 SkillResult result; + private final SkillMetadata result; /** * Called right after a player casts a skill. @@ -18,7 +18,7 @@ public class PlayerPostCastSkillEvent extends PlayerDataEvent { * @param skill Skill being cast * @param result SKill casting result */ - public PlayerPostCastSkillEvent(PlayerData playerData, SkillInfo skill, SkillResult result) { + public PlayerPostCastSkillEvent(PlayerData playerData, SkillInfo skill, SkillMetadata result) { super(playerData); this.skill = skill; @@ -29,7 +29,7 @@ public class PlayerPostCastSkillEvent extends PlayerDataEvent { return skill; } - public SkillResult getResult() { + public SkillMetadata getResult() { return result; } diff --git a/src/main/java/net/Indyuce/mmocore/api/event/PlayerPreCastSkillEvent.java b/src/main/java/net/Indyuce/mmocore/api/event/PlayerPreCastSkillEvent.java index 19f48876..4bbc45db 100644 --- a/src/main/java/net/Indyuce/mmocore/api/event/PlayerPreCastSkillEvent.java +++ b/src/main/java/net/Indyuce/mmocore/api/event/PlayerPreCastSkillEvent.java @@ -1,7 +1,7 @@ package net.Indyuce.mmocore.api.event; import net.Indyuce.mmocore.api.player.PlayerData; -import net.Indyuce.mmocore.api.skill.Skill.SkillInfo; +import net.Indyuce.mmocore.skill.Skill.SkillInfo; import org.bukkit.event.Cancellable; import org.bukkit.event.HandlerList; diff --git a/src/main/java/net/Indyuce/mmocore/api/event/PlayerResourceUpdateEvent.java b/src/main/java/net/Indyuce/mmocore/api/event/PlayerResourceUpdateEvent.java index 61d6b4fb..a364a43f 100644 --- a/src/main/java/net/Indyuce/mmocore/api/event/PlayerResourceUpdateEvent.java +++ b/src/main/java/net/Indyuce/mmocore/api/event/PlayerResourceUpdateEvent.java @@ -2,6 +2,7 @@ package net.Indyuce.mmocore.api.event; import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.player.profess.resource.PlayerResource; +import net.Indyuce.mmocore.skill.list.Neptune_Gift; import org.bukkit.event.Cancellable; import org.bukkit.event.HandlerList; @@ -27,7 +28,7 @@ public class PlayerResourceUpdateEvent extends PlayerDataEvent implements Cancel * Called when a player gains some resource back. This can * be used to handle stats like health or mana regeneration. *

- * Example use: {@link net.Indyuce.mmocore.skill.Neptune_Gift} which is a skill + * Example use: {@link Neptune_Gift} which is a skill * that temporarily increases resource regeneration for a short amount of time. * * @param playerData Player regenerating 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 b6bc9b7f..c43bc896 100644 --- a/src/main/java/net/Indyuce/mmocore/api/player/PlayerData.java +++ b/src/main/java/net/Indyuce/mmocore/api/player/PlayerData.java @@ -23,6 +23,7 @@ import net.Indyuce.mmocore.api.util.MMOCoreUtils; import net.Indyuce.mmocore.api.util.math.particle.SmallParticleEffect; import net.Indyuce.mmocore.listener.SpellCast.SkillCasting; import net.Indyuce.mmocore.manager.SoundManager; +import net.Indyuce.mmocore.skill.CasterMetadata; import net.Indyuce.mmocore.skill.PlayerSkillData; import net.Indyuce.mmocore.skill.Skill; import net.Indyuce.mmocore.skill.Skill.SkillInfo; @@ -819,7 +820,8 @@ public class PlayerData extends OfflinePlayerData { return new SkillMetadata(this, skill, CancelReason.OTHER); // Check for mana/stamina/cooldown and cast skill - SkillMetadata cast = skill.getSkill().whenCast(this, skill); + CasterMetadata casterMeta = new CasterMetadata(this); + SkillMetadata cast = skill.getSkill().whenCast(casterMeta, skill); // Send failure messages if (!cast.isSuccessful()) { diff --git a/src/main/java/net/Indyuce/mmocore/api/player/profess/PlayerClass.java b/src/main/java/net/Indyuce/mmocore/api/player/profess/PlayerClass.java index aa9ab37e..75617547 100644 --- a/src/main/java/net/Indyuce/mmocore/api/player/profess/PlayerClass.java +++ b/src/main/java/net/Indyuce/mmocore/api/player/profess/PlayerClass.java @@ -14,8 +14,8 @@ import net.Indyuce.mmocore.api.player.profess.resource.ManaDisplayOptions; import net.Indyuce.mmocore.api.player.profess.resource.PlayerResource; import net.Indyuce.mmocore.api.player.profess.resource.ResourceHandler; import net.Indyuce.mmocore.api.player.stats.StatType; -import net.Indyuce.mmocore.api.skill.Skill; -import net.Indyuce.mmocore.api.skill.Skill.SkillInfo; +import net.Indyuce.mmocore.skill.Skill; +import net.Indyuce.mmocore.skill.Skill.SkillInfo; import net.Indyuce.mmocore.api.util.MMOCoreUtils; import net.Indyuce.mmocore.api.util.math.formula.LinearValue; import net.Indyuce.mmocore.api.util.math.particle.CastingParticle; diff --git a/src/main/java/net/Indyuce/mmocore/api/player/profess/SavedClassInformation.java b/src/main/java/net/Indyuce/mmocore/api/player/profess/SavedClassInformation.java index 9d503eb8..3f37599c 100644 --- a/src/main/java/net/Indyuce/mmocore/api/player/profess/SavedClassInformation.java +++ b/src/main/java/net/Indyuce/mmocore/api/player/profess/SavedClassInformation.java @@ -13,7 +13,7 @@ import com.google.gson.JsonObject; import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.player.attribute.PlayerAttribute; -import net.Indyuce.mmocore.api.skill.Skill; +import net.Indyuce.mmocore.skill.Skill; import net.Indyuce.mmocore.manager.data.PlayerDataManager.DefaultPlayerData; public class SavedClassInformation { diff --git a/src/main/java/net/Indyuce/mmocore/api/player/profess/event/trigger/AttackEventTrigger.java b/src/main/java/net/Indyuce/mmocore/api/player/profess/event/trigger/AttackEventTrigger.java index 676c3c98..7df652ea 100644 --- a/src/main/java/net/Indyuce/mmocore/api/player/profess/event/trigger/AttackEventTrigger.java +++ b/src/main/java/net/Indyuce/mmocore/api/player/profess/event/trigger/AttackEventTrigger.java @@ -1,33 +1,32 @@ package net.Indyuce.mmocore.api.player.profess.event.trigger; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; - +import io.lumine.mythic.lib.api.event.PlayerAttackEvent; +import io.lumine.mythic.lib.damage.DamageType; import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.player.profess.PlayerClass; import net.Indyuce.mmocore.api.player.profess.event.EventTriggerHandler; -import io.lumine.mythic.lib.api.DamageType; -import io.lumine.mythic.lib.api.event.PlayerAttackEvent; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; public class AttackEventTrigger implements EventTriggerHandler { - @Override - public boolean handles(String event) { - return event.endsWith("-damage"); - } + @Override + public boolean handles(String event) { + return event.endsWith("-damage"); + } - @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) - public void a(PlayerAttackEvent event) { - // We don't want players dying by themselves when using an enderpearl. - if(event.getPlayer().equals(event.getEntity())) return; + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void a(PlayerAttackEvent event) { + // We don't want players dying by themselves when using an enderpearl. + if (event.getPlayer().equals(event.getEntity())) return; - PlayerData player = PlayerData.get(event.getData().getUniqueId()); - PlayerClass profess = player.getProfess(); + PlayerData player = PlayerData.get(event.getData().getUniqueId()); + PlayerClass profess = player.getProfess(); - for (DamageType type : event.getAttack().getTypes()) { - String path = type.getPath() + "-damage"; - if (profess.hasEventTriggers(path)) - profess.getEventTriggers(path).getTriggers().forEach(trigger -> trigger.apply(player)); - } - } + for (DamageType type : event.getAttack().getDamage().collectTypes()) { + String path = type.getPath() + "-damage"; + if (profess.hasEventTriggers(path)) + profess.getEventTriggers(path).getTriggers().forEach(trigger -> trigger.apply(player)); + } + } } diff --git a/src/main/java/net/Indyuce/mmocore/api/skill/SkillResult.java b/src/main/java/net/Indyuce/mmocore/api/skill/SkillResult.java deleted file mode 100644 index 7f0dea1e..00000000 --- a/src/main/java/net/Indyuce/mmocore/api/skill/SkillResult.java +++ /dev/null @@ -1,105 +0,0 @@ -package net.Indyuce.mmocore.api.skill; - -import net.Indyuce.mmocore.MMOCore; -import net.Indyuce.mmocore.api.player.PlayerData; -import net.Indyuce.mmocore.api.skill.Skill.SkillInfo; -import net.Indyuce.mmocore.comp.flags.FlagPlugin.CustomFlag; - -public class SkillResult { - private final SkillInfo skill; - private final int level; - private final double mana, cooldown, stamina; - - private CancelReason cancelReason; - - public SkillResult(PlayerData data, SkillInfo skill) { - this.skill = skill; - - level = data.getSkillLevel(skill.getSkill()); - cooldown = (skill.getSkill().hasModifier("cooldown") ? data.getSkillData().getCooldown(skill) : 0); - mana = (skill.getSkill().hasModifier("mana") ? skill.getModifier("mana", level) : 0); - stamina = (skill.getSkill().hasModifier("stamina") ? skill.getModifier("stamina", level) : 0); - cancelReason = !data.hasSkillUnlocked(skill) ? CancelReason.LOCKED - : cooldown > 0 ? CancelReason.COOLDOWN - : mana > data.getMana() ? CancelReason.MANA - : stamina > data.getStamina() ? CancelReason.STAMINA - : !MMOCore.plugin.flagPlugin.isFlagAllowed(data.getPlayer(), CustomFlag.SKILLS) - ? CancelReason.FLAG - : null; - } - - public SkillResult(PlayerData data, SkillInfo skill, CancelReason reason) { - this.skill = skill; - this.cancelReason = reason; - - level = data.getSkillLevel(skill.getSkill()); - cooldown = skill.getSkill().hasModifier("cooldown") ? data.getSkillData().getCooldown(skill) : 0; - mana = skill.getSkill().hasModifier("mana") ? skill.getModifier("mana", level) : 0; - stamina = (skill.getSkill().hasModifier("stamina") ? skill.getModifier("stamina", level) : 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 = reason; - } - - public double getModifier(String modifier) { - return skill.getModifier(modifier, level); - } - - public enum CancelReason { - - // skill flag - FLAG, - - // not enough mana - MANA, - - // not enough stamina - STAMINA, - - // skill still on cooldown - COOLDOWN, - - // skill still not unlocked - LOCKED, - - // no reason specified - OTHER - } -} diff --git a/src/main/java/net/Indyuce/mmocore/api/skill/result/LocationSkillResult.java b/src/main/java/net/Indyuce/mmocore/api/skill/result/LocationSkillResult.java deleted file mode 100644 index e13acc22..00000000 --- a/src/main/java/net/Indyuce/mmocore/api/skill/result/LocationSkillResult.java +++ /dev/null @@ -1,53 +0,0 @@ -package net.Indyuce.mmocore.api.skill.result; - -import org.bukkit.FluidCollisionMode; -import org.bukkit.Location; -import org.bukkit.util.RayTraceResult; - -import net.Indyuce.mmocore.api.player.PlayerData; -import net.Indyuce.mmocore.api.skill.Skill.SkillInfo; -import net.Indyuce.mmocore.api.skill.SkillResult; -import net.Indyuce.mmocore.api.util.MMOCoreUtils; - -public class LocationSkillResult extends SkillResult { - private Location loc; - - /** - * @param data Player casting the skill - * @param skill Skill being cast - * @param range Skill raycast range - */ - public LocationSkillResult(PlayerData data, SkillInfo skill, double range) { - this(data, skill, range, false); - } - - /** - * @param data Player casting the skill - * @param skill Skill being cast - * @param range Skill raycast range - * @param buff If the skill is a buff ie if it can be cast on party members - */ - public LocationSkillResult(PlayerData data, SkillInfo skill, double range, boolean buff) { - super(data, skill); - - if (isSuccessful()) { - - RayTraceResult result = data.getPlayer().getWorld().rayTrace(data.getPlayer().getEyeLocation(), - data.getPlayer().getEyeLocation().getDirection(), range, FluidCollisionMode.ALWAYS, true, 1.0D, - entity -> MMOCoreUtils.canTarget(data, entity, buff)); - 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/api/skill/result/TargetSkillResult.java b/src/main/java/net/Indyuce/mmocore/api/skill/result/TargetSkillResult.java deleted file mode 100644 index c5e3d34d..00000000 --- a/src/main/java/net/Indyuce/mmocore/api/skill/result/TargetSkillResult.java +++ /dev/null @@ -1,52 +0,0 @@ -package net.Indyuce.mmocore.api.skill.result; - -import org.bukkit.entity.LivingEntity; - -import net.Indyuce.mmocore.api.player.PlayerData; -import net.Indyuce.mmocore.api.skill.Skill.SkillInfo; -import net.Indyuce.mmocore.api.skill.SkillResult; -import net.Indyuce.mmocore.api.util.MMOCoreUtils; -import io.lumine.mythic.lib.MythicLib; -import io.lumine.mythic.lib.api.MMORayTraceResult; - -public class TargetSkillResult extends SkillResult { - private LivingEntity target; - - /** - * @param data Player casting the skill - * @param skill Skill being cast - * @param range Skill raycast range - */ - public TargetSkillResult(PlayerData data, SkillInfo skill, double range) { - this(data, skill, range, false); - } - - /** - * @param data Player casting the skill - * @param skill Skill being cast - * @param range Skill raycast range - * @param buff If the skill is a buff ie if it can be cast on party members - */ - public TargetSkillResult(PlayerData data, SkillInfo skill, double range, boolean buff) { - super(data, skill); - - if (isSuccessful()) { - MMORayTraceResult result = MythicLib.plugin.getVersion().getWrapper().rayTrace(data.getPlayer(), range, - entity -> MMOCoreUtils.canTarget(data, entity, buff)); - if (!result.hasHit()) - abort(); - else - target = result.getHit(); - } - } - - // check skill result abort reason instead - @Deprecated - public boolean hasTarget() { - return target != null; - } - - public LivingEntity getTarget() { - return target; - } -} diff --git a/src/main/java/net/Indyuce/mmocore/command/rpg/booster/ListCommandTreeNode.java b/src/main/java/net/Indyuce/mmocore/command/rpg/booster/ListCommandTreeNode.java index 2c57f5df..73363fa9 100644 --- a/src/main/java/net/Indyuce/mmocore/command/rpg/booster/ListCommandTreeNode.java +++ b/src/main/java/net/Indyuce/mmocore/command/rpg/booster/ListCommandTreeNode.java @@ -21,7 +21,7 @@ public class ListCommandTreeNode extends CommandTreeNode { return CommandResult.FAILURE; sender.sendMessage(ChatColor.YELLOW + "----------------------------------------------------"); - for (Booster booster : MMOCore.plugin.boosterManager.getBoosters()) + for (Booster booster : MMOCore.plugin.boosterManager.getActive()) if (!booster.isTimedOut()) MythicLib.plugin.getVersion().getWrapper().sendJson((Player) sender, "{\"text\":\"" + ChatColor.YELLOW + "- " + ChatColor.GOLD + MythicLib.plugin.getMMOConfig().decimal.format((1 + booster.getExtra())) + "x" + ChatColor.YELLOW + " Booster - " diff --git a/src/main/java/net/Indyuce/mmocore/command/rpg/booster/RemoveCommandTreeNode.java b/src/main/java/net/Indyuce/mmocore/command/rpg/booster/RemoveCommandTreeNode.java index 9c07520a..c10cd4dd 100644 --- a/src/main/java/net/Indyuce/mmocore/command/rpg/booster/RemoveCommandTreeNode.java +++ b/src/main/java/net/Indyuce/mmocore/command/rpg/booster/RemoveCommandTreeNode.java @@ -16,7 +16,7 @@ public class RemoveCommandTreeNode extends CommandTreeNode { super(parent, "remove"); addParameter(new Parameter("", - (explorer, list) -> MMOCore.plugin.boosterManager.getBoosters().forEach(booster -> list.add("" + booster.getUniqueId().toString())))); + (explorer, list) -> MMOCore.plugin.boosterManager.getActive().forEach(booster -> list.add("" + booster.getUniqueId().toString())))); } @Override @@ -32,7 +32,7 @@ public class RemoveCommandTreeNode extends CommandTreeNode { return CommandResult.FAILURE; } - for (Iterator iterator = MMOCore.plugin.boosterManager.getBoosters().iterator(); iterator.hasNext();) { + for (Iterator iterator = MMOCore.plugin.boosterManager.getActive().iterator(); iterator.hasNext();) { Booster booster = iterator.next(); if (booster.getUniqueId().equals(uuid)) { iterator.remove(); diff --git a/src/main/java/net/Indyuce/mmocore/comp/mythicmobs/MythicMobsDrops.java b/src/main/java/net/Indyuce/mmocore/comp/mythicmobs/MythicMobsDrops.java index 30944d24..2a784ef7 100644 --- a/src/main/java/net/Indyuce/mmocore/comp/mythicmobs/MythicMobsDrops.java +++ b/src/main/java/net/Indyuce/mmocore/comp/mythicmobs/MythicMobsDrops.java @@ -1,8 +1,5 @@ package net.Indyuce.mmocore.comp.mythicmobs; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; - import io.lumine.xikage.mythicmobs.MythicMobs; import io.lumine.xikage.mythicmobs.api.bukkit.events.MythicDropLoadEvent; import io.lumine.xikage.mythicmobs.api.bukkit.events.MythicReloadedEvent; @@ -10,40 +7,43 @@ import io.lumine.xikage.mythicmobs.skills.placeholders.Placeholder; import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.comp.mythicmobs.load.CurrencyItemDrop; import net.Indyuce.mmocore.comp.mythicmobs.load.GoldPouchDrop; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; public class MythicMobsDrops implements Listener { - public MythicMobsDrops() { - registerPlaceholders(); - } + public MythicMobsDrops() { + registerPlaceholders(); + } - @EventHandler - public void a(MythicDropLoadEvent event) { + @EventHandler + public void a(MythicDropLoadEvent event) { - // random gold pouches - if (event.getDropName().equalsIgnoreCase("gold_pouch") || event.getDropName().equalsIgnoreCase("goldpouch")) - event.register(new GoldPouchDrop(event.getConfig())); + // random gold pouches + if (event.getDropName().equalsIgnoreCase("gold_pouch") || event.getDropName().equalsIgnoreCase("goldpouch")) + event.register(new GoldPouchDrop(event.getConfig())); - // gold coins - if (event.getDropName().equalsIgnoreCase("gold_coin") || event.getDropName().equalsIgnoreCase("coin")) - event.register(new CurrencyItemDrop("GOLD_COIN", event.getConfig())); + // gold coins + if (event.getDropName().equalsIgnoreCase("gold_coin") || event.getDropName().equalsIgnoreCase("coin")) + event.register(new CurrencyItemDrop("GOLD_COIN", event.getConfig())); - // notes - if (event.getDropName().equalsIgnoreCase("note") || event.getDropName().equalsIgnoreCase("banknote") || event.getDropName().equalsIgnoreCase("bank_note")) - event.register(new CurrencyItemDrop("NOTE", event.getConfig())); - } + // notes + if (event.getDropName().equalsIgnoreCase("note") || event.getDropName().equalsIgnoreCase("banknote") || event.getDropName().equalsIgnoreCase("bank_note")) + event.register(new CurrencyItemDrop("NOTE", event.getConfig())); + } - /* - * when MythicMobs is reloaded, the placeholders are emptied. Add them again - */ - @EventHandler - public void b(MythicReloadedEvent event) { - registerPlaceholders(); - } + /* + * when MythicMobs is reloaded, the placeholders are emptied. Add them again + */ + @EventHandler + public void b(MythicReloadedEvent event) { + registerPlaceholders(); + } - private void registerPlaceholders() { - MythicMobs.inst().getPlaceholderManager().register("mmocore.skill", Placeholder.meta((metadata, arg) -> String.valueOf(PlayerData.get(metadata.getCaster().getEntity().getUniqueId()).getSkillData().getCachedModifier(arg)))); - MythicMobs.inst().getPlaceholderManager().register("mmocore.skill.int", Placeholder.meta((metadata, arg) -> String.valueOf((int) PlayerData.get(metadata.getCaster().getEntity().getUniqueId()).getSkillData().getCachedModifier(arg)))); - MythicMobs.inst().getPlaceholderManager().register("mmocore.mana", Placeholder.meta((metadata, arg) -> String.valueOf((int) PlayerData.get(metadata.getCaster().getEntity().getUniqueId()).getMana()))); - MythicMobs.inst().getPlaceholderManager().register("mmocore.stamina", Placeholder.meta((metadata, arg) -> String.valueOf((int) PlayerData.get(metadata.getCaster().getEntity().getUniqueId()).getStamina()))); - } + private void registerPlaceholders() { + // TODO + /*MythicMobs.inst().getPlaceholderManager().register("mmocore.skill", Placeholder.meta((metadata, arg) -> String.valueOf(PlayerData.get(metadata.getCaster().getEntity().getUniqueId()).getSkillData().getCachedModifier(arg)))); + MythicMobs.inst().getPlaceholderManager().register("mmocore.skill.int", Placeholder.meta((metadata, arg) -> String.valueOf((int) PlayerData.get(metadata.getCaster().getEntity().getUniqueId()).getSkillData().getCachedModifier(arg))));*/ + MythicMobs.inst().getPlaceholderManager().register("mmocore.mana", Placeholder.meta((metadata, arg) -> String.valueOf((int) PlayerData.get(metadata.getCaster().getEntity().getUniqueId()).getMana()))); + MythicMobs.inst().getPlaceholderManager().register("mmocore.stamina", Placeholder.meta((metadata, arg) -> String.valueOf((int) PlayerData.get(metadata.getCaster().getEntity().getUniqueId()).getStamina()))); + } } \ No newline at end of file diff --git a/src/main/java/net/Indyuce/mmocore/comp/mythicmobs/skill/MythicMobSkill.java b/src/main/java/net/Indyuce/mmocore/comp/mythicmobs/skill/MythicMobSkill.java index c93b6380..693851a8 100644 --- a/src/main/java/net/Indyuce/mmocore/comp/mythicmobs/skill/MythicMobSkill.java +++ b/src/main/java/net/Indyuce/mmocore/comp/mythicmobs/skill/MythicMobSkill.java @@ -2,112 +2,117 @@ package net.Indyuce.mmocore.comp.mythicmobs.skill; import io.lumine.mythic.lib.api.util.EnumUtils; 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.player.PlayerData; -import net.Indyuce.mmocore.api.skill.Skill; -import net.Indyuce.mmocore.api.skill.SkillResult; -import net.Indyuce.mmocore.api.skill.SkillResult.CancelReason; 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.bukkit.entity.Entity; -import java.util.*; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Optional; import java.util.logging.Level; public class MythicMobSkill extends Skill { - private final io.lumine.xikage.mythicmobs.skills.Skill skill; - private final Map antiCheat = new HashMap<>(); + private final io.lumine.xikage.mythicmobs.skills.Skill skill; + private final Map antiCheat = new HashMap<>(); - //private final BiFunction cast; + public MythicMobSkill(String id, FileConfiguration config) { + super(id); - public MythicMobSkill(String id, FileConfiguration config) { - super(id); + String mmId = config.getString("mythicmobs-skill-id"); + Validate.notNull(mmId, "Could not find MM skill 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(); - 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)); - 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")); - 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)); + } - 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.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(PassiveSkillType.class, config.getString("passive-type").toUpperCase()); + Validate.isTrue(passiveType.isPresent(), "Invalid passive skill type"); + setPassive(); + Bukkit.getPluginManager().registerEvents(passiveType.get().getHandler(this), MMOCore.plugin); + } + } - if (config.isString("passive-type")) { - Optional passiveType = EnumUtils.getIfPresent(PassiveSkillType.class, config.getString("passive-type").toUpperCase()); - Validate.isTrue(passiveType.isPresent(), "Invalid passive skill type"); - setPassive(); - Bukkit.getPluginManager().registerEvents(passiveType.get().getHandler(this), MMOCore.plugin); - } + public Map getAntiCheat() { + return antiCheat; + } - // cast = config.getBoolean("target") ? (data, info) -> new - // TargetSkillResult(data, info, def(config.getDouble("range"), 50)) : - // (data, info) -> new SkillResult(data, info); - } + public String getInternalName() { + return skill.getInternalName(); + } - public Map getAntiCheat() { - return antiCheat; - } + public io.lumine.xikage.mythicmobs.skills.Skill getSkill() { + return skill; + } - public String getInternalName() { - return skill.getInternalName(); - } + @Override + public SkillMetadata whenCast(CasterMetadata caster, SkillInfo skill) { + SkillMetadata cast = new SkillMetadata(caster, skill); + if (!cast.isSuccessful() || isPassive()) + return cast; - @Override - public SkillResult whenCast(PlayerData data, SkillInfo skill) { - SkillResult cast = new SkillResult(data, skill); - if (!cast.isSuccessful() || !data.isOnline() || isPassive()) - return cast; + HashSet targetEntities = new HashSet<>(); + HashSet targetLocations = new HashSet<>(); - List targets = new ArrayList<>(); - // targets.add(cast instanceof TargetSkillResult ? ((TargetSkillResult) - // cast).getTarget() : stats.getPlayer()); - targets.add(data.getPlayer()); + 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); - /* - * cache placeholders so they can be retrieved later by MythicMobs math - * formulas - */ - data.getSkillData().cacheModifiers(this, cast); - if (MMOCore.plugin.hasAntiCheat()) - MMOCore.plugin.antiCheatSupport.disableAntiCheat(data.getPlayer(), antiCheat); - if (!MythicMobs.inst().getAPIHelper().castSkill(data.getPlayer(), this.skill.getInternalName(), data.getPlayer(), - data.getPlayer().getEyeLocation(), targets, null, 1)) - cast.abort(CancelReason.OTHER); + // Disable anticheat + if (MMOCore.plugin.hasAntiCheat()) + MMOCore.plugin.antiCheatSupport.disableAntiCheat(caster.getPlayer(), antiCheat); - return cast; - } + if (this.skill.usable(skillMeta, SkillTrigger.API)) + this.skill.execute(skillMeta); + else + cast.abort(); - /** - * 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); - } + 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); + } } diff --git a/src/main/java/net/Indyuce/mmocore/comp/mythicmobs/skill/PassiveMythicMobSkillHandler.java b/src/main/java/net/Indyuce/mmocore/comp/mythicmobs/skill/PassiveMythicMobSkillHandler.java index 5de8046b..121835fd 100644 --- a/src/main/java/net/Indyuce/mmocore/comp/mythicmobs/skill/PassiveMythicMobSkillHandler.java +++ b/src/main/java/net/Indyuce/mmocore/comp/mythicmobs/skill/PassiveMythicMobSkillHandler.java @@ -1,40 +1,65 @@ package net.Indyuce.mmocore.comp.mythicmobs.skill; -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.player.PlayerData; -import net.Indyuce.mmocore.api.skill.SkillResult; +import net.Indyuce.mmocore.skill.CasterMetadata; +import net.Indyuce.mmocore.skill.Skill; +import net.Indyuce.mmocore.skill.metadata.SkillMetadata; import org.bukkit.entity.Entity; import org.bukkit.event.Listener; -import java.util.Collections; +import java.util.HashSet; public abstract class PassiveMythicMobSkillHandler implements Listener { - protected final MythicMobSkill skill; - - /** - * Core class for all passive types - */ - protected PassiveMythicMobSkillHandler(MythicMobSkill skill) { - this.skill = skill; - } - - public void castSkill(PlayerData data) { - castSkill(data, data.getPlayer()); - } + protected final MythicMobSkill skill; - public void castSkill(PlayerData data, Entity target) { - if (!data.getProfess().hasSkill(skill.getId())) - return; + /** + * Core class for all passive types + */ + protected PassiveMythicMobSkillHandler(MythicMobSkill skill) { + this.skill = skill; + } - SkillResult cast = data.cast(data.getProfess().getSkill(skill.getId())); - if (!cast.isSuccessful()) - return; + public SkillMetadata castSkill(PlayerData data) { + return castSkill(data, null); + } - data.getSkillData().cacheModifiers(skill.getInternalName(), cast); - if (MMOCore.plugin.hasAntiCheat()) - MMOCore.plugin.antiCheatSupport.disableAntiCheat(data.getPlayer(), skill.getAntiCheat()); - MythicMobs.inst().getAPIHelper().castSkill(data.getPlayer(), skill.getInternalName(), target, - data.getPlayer().getEyeLocation(), Collections.singletonList(data.getPlayer()), null, 1); - } + public SkillMetadata castSkill(PlayerData playerData, Entity target) { + if (!playerData.getProfess().hasSkill(skill)) + return null; + + Skill.SkillInfo skill = playerData.getProfess().getSkill(this.skill); + CasterMetadata caster = new CasterMetadata(playerData); + SkillMetadata cast = new SkillMetadata(caster, skill); + if (!cast.isSuccessful() || this.skill.isPassive()) + return cast; + + HashSet targetEntities = new HashSet<>(); + HashSet targetLocations = new HashSet<>(); + + // The only difference + if (target != null) + targetEntities.add(BukkitAdapter.adapt(target)); + + 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); + + // Disable anticheat + if (MMOCore.plugin.hasAntiCheat()) + MMOCore.plugin.antiCheatSupport.disableAntiCheat(caster.getPlayer(), this.skill.getAntiCheat()); + + if (this.skill.getSkill().usable(skillMeta, SkillTrigger.API)) + this.skill.getSkill().execute(skillMeta); + else + cast.abort(); + + return cast; + } } diff --git a/src/main/java/net/Indyuce/mmocore/comp/mythicmobs/skill/handlers/PlayerDamageSkillHandler.java b/src/main/java/net/Indyuce/mmocore/comp/mythicmobs/skill/handlers/PlayerDamageSkillHandler.java index 8f818ab4..7658185e 100644 --- a/src/main/java/net/Indyuce/mmocore/comp/mythicmobs/skill/handlers/PlayerDamageSkillHandler.java +++ b/src/main/java/net/Indyuce/mmocore/comp/mythicmobs/skill/handlers/PlayerDamageSkillHandler.java @@ -18,8 +18,8 @@ public class PlayerDamageSkillHandler extends PassiveMythicMobSkillHandler { } @EventHandler - private void event(EntityDamageEvent e) { - if (e.getEntityType() == EntityType.PLAYER && !e.getEntity().hasMetadata("NPC")) - castSkill(PlayerData.get((Player) e.getEntity())); + private void event(EntityDamageEvent event) { + if (event.getEntityType() == EntityType.PLAYER && !event.getEntity().hasMetadata("NPC")) + castSkill(PlayerData.get((Player) event.getEntity())); } } diff --git a/src/main/java/net/Indyuce/mmocore/gui/PlayerStats.java b/src/main/java/net/Indyuce/mmocore/gui/PlayerStats.java index 60c2a345..6bac95e8 100644 --- a/src/main/java/net/Indyuce/mmocore/gui/PlayerStats.java +++ b/src/main/java/net/Indyuce/mmocore/gui/PlayerStats.java @@ -10,7 +10,6 @@ import net.Indyuce.mmocore.api.player.stats.StatType; import net.Indyuce.mmocore.api.util.math.format.DelayFormat; import net.Indyuce.mmocore.gui.api.EditableInventory; import net.Indyuce.mmocore.gui.api.GeneratedInventory; -import net.Indyuce.mmocore.gui.api.PluginInventory; import net.Indyuce.mmocore.gui.api.item.InventoryItem; import net.Indyuce.mmocore.gui.api.item.Placeholders; import net.Indyuce.mmocore.gui.api.item.SimplePlaceholderItem; @@ -43,7 +42,7 @@ public class PlayerStats extends EditableInventory { @Override public boolean canDisplay(PlayerStatsInventory inv) { InventoryItem boost = inv.getByFunction("boost"); - return boost != null && inv.boostOffset + boost.getSlots().size() < MMOCore.plugin.boosterManager.getBoosters().size(); + return boost != null && inv.boostOffset + boost.getSlots().size() < MMOCore.plugin.boosterManager.getActive().size(); } }; @@ -304,7 +303,7 @@ public class PlayerStats extends EditableInventory { @Override public ItemStack display(PlayerStatsInventory inv, int n) { int offset = inv.boostOffset; - if (n + offset >= MMOCore.plugin.boosterManager.getBoosters().size()) + if (n + offset >= MMOCore.plugin.boosterManager.getActive().size()) return noBoost.display(inv, n); Booster boost = MMOCore.plugin.boosterManager.get(inv.boostOffset + n); diff --git a/src/main/java/net/Indyuce/mmocore/gui/SkillList.java b/src/main/java/net/Indyuce/mmocore/gui/SkillList.java index a1beb56e..e5e2ba01 100644 --- a/src/main/java/net/Indyuce/mmocore/gui/SkillList.java +++ b/src/main/java/net/Indyuce/mmocore/gui/SkillList.java @@ -5,8 +5,8 @@ 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.api.skill.Skill; -import net.Indyuce.mmocore.api.skill.Skill.SkillInfo; +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; diff --git a/src/main/java/net/Indyuce/mmocore/gui/api/GeneratedInventory.java b/src/main/java/net/Indyuce/mmocore/gui/api/GeneratedInventory.java index 4fe60788..b3cca611 100644 --- a/src/main/java/net/Indyuce/mmocore/gui/api/GeneratedInventory.java +++ b/src/main/java/net/Indyuce/mmocore/gui/api/GeneratedInventory.java @@ -1,16 +1,15 @@ package net.Indyuce.mmocore.gui.api; -import java.util.ArrayList; -import java.util.List; - +import io.lumine.mythic.lib.MythicLib; +import net.Indyuce.mmocore.api.player.PlayerData; +import net.Indyuce.mmocore.gui.api.item.InventoryItem; +import net.Indyuce.mmocore.gui.api.item.TriggerItem; import org.bukkit.Bukkit; import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.inventory.Inventory; -import net.Indyuce.mmocore.api.player.PlayerData; -import net.Indyuce.mmocore.gui.api.item.InventoryItem; -import net.Indyuce.mmocore.gui.api.item.TriggerItem; -import io.lumine.mythic.lib.MythicLib; +import java.util.ArrayList; +import java.util.List; public abstract class GeneratedInventory extends PluginInventory { private final EditableInventory editable; @@ -44,9 +43,10 @@ public abstract class GeneratedInventory extends PluginInventory { return null; } - /* - * this method must use an ordered collection because of GUI items - * overriding possibilities. + /** + * This method must use an ordered collection because + * of GUI items overriding possibilities. Hence the use + * of an array list instead of a set */ public void addLoaded(InventoryItem item) { loaded.add(0, item); @@ -66,7 +66,7 @@ public abstract class GeneratedInventory extends PluginInventory { public void open() { /* - * very important, in order to prevent ghost items, the loaded items map + * Very important, in order to prevent ghost items, the loaded items map * must be cleared when the inventory is updated or open at least twice */ loaded.clear(); diff --git a/src/main/java/net/Indyuce/mmocore/listener/SpellCast.java b/src/main/java/net/Indyuce/mmocore/listener/SpellCast.java index 537ae3cc..06580e32 100644 --- a/src/main/java/net/Indyuce/mmocore/listener/SpellCast.java +++ b/src/main/java/net/Indyuce/mmocore/listener/SpellCast.java @@ -13,7 +13,7 @@ import org.bukkit.scheduler.BukkitRunnable; import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.api.player.PlayerData; -import net.Indyuce.mmocore.api.skill.Skill.SkillInfo; +import net.Indyuce.mmocore.skill.Skill.SkillInfo; import net.Indyuce.mmocore.manager.ConfigManager; import net.Indyuce.mmocore.manager.SoundManager; diff --git a/src/main/java/net/Indyuce/mmocore/listener/option/PlayerProfileCheck.java b/src/main/java/net/Indyuce/mmocore/listener/option/PlayerProfileCheck.java new file mode 100644 index 00000000..c0080fc7 --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/listener/option/PlayerProfileCheck.java @@ -0,0 +1,29 @@ +package net.Indyuce.mmocore.listener.option; + +import io.lumine.mythic.lib.MythicLib; +import net.Indyuce.mmocore.api.player.PlayerData; +import net.Indyuce.mmocore.manager.InventoryManager; +import org.bukkit.entity.EntityType; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerInteractEntityEvent; +import org.bukkit.inventory.Inventory; + +public class PlayerProfileCheck implements Listener { + + @EventHandler + public void a(PlayerInteractEntityEvent event) { + if (event.getRightClicked().getType() != EntityType.PLAYER || MythicLib.plugin.getEntities().findCustom(event.getRightClicked())) + return; + + /* + * This works because the PlayerStats class DOES NOT utilize + * at all the player instance saved in the InventoryClickEvent + * + * Opening inventories like that to other players does NOT + * necessarily works for any other custom inventory. + * */ + Inventory inv = InventoryManager.PLAYER_STATS.newInventory(PlayerData.get(event.getRightClicked().getUniqueId())).getInventory(); + event.getPlayer().openInventory(inv); + } +} diff --git a/src/main/java/net/Indyuce/mmocore/manager/SkillManager.java b/src/main/java/net/Indyuce/mmocore/manager/SkillManager.java index ae5444e0..edbebb22 100644 --- a/src/main/java/net/Indyuce/mmocore/manager/SkillManager.java +++ b/src/main/java/net/Indyuce/mmocore/manager/SkillManager.java @@ -17,7 +17,7 @@ import org.bukkit.configuration.file.YamlConfiguration; import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.api.ConfigFile; -import net.Indyuce.mmocore.api.skill.Skill; +import net.Indyuce.mmocore.skill.Skill; import net.Indyuce.mmocore.api.util.math.formula.LinearValue; import net.Indyuce.mmocore.comp.mythicmobs.skill.MythicMobSkill; @@ -36,7 +36,7 @@ public class SkillManager { 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/") + 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", "")) .newInstance()); diff --git a/src/main/java/net/Indyuce/mmocore/manager/social/BoosterManager.java b/src/main/java/net/Indyuce/mmocore/manager/social/BoosterManager.java index c9590faf..d689c014 100644 --- a/src/main/java/net/Indyuce/mmocore/manager/social/BoosterManager.java +++ b/src/main/java/net/Indyuce/mmocore/manager/social/BoosterManager.java @@ -41,7 +41,7 @@ public class BoosterManager { /** * Cleans timed out boosters from the MMOCore registry */ - public void flush() { + private void flush() { map.removeIf(Booster::isTimedOut); } @@ -66,14 +66,7 @@ public class BoosterManager { * @return Collection of currently registered boosters. Some of them can be * expired but are not unregistered yet! */ - public List getBoosters() { - return map; - } - - /** - * @return Same as {@link #getBoosters()} but does not include timed out boosters - */ - public List getActiveBoosters() { + public List getActive() { return map.stream().filter((b) -> !b.isTimedOut()).collect(Collectors.toList()); } } diff --git a/src/main/java/net/Indyuce/mmocore/skill/Ambers.java b/src/main/java/net/Indyuce/mmocore/skill/Ambers.java deleted file mode 100644 index a6338a21..00000000 --- a/src/main/java/net/Indyuce/mmocore/skill/Ambers.java +++ /dev/null @@ -1,88 +0,0 @@ -package net.Indyuce.mmocore.skill; - -import io.lumine.mythic.lib.api.DamageType; -import io.lumine.mythic.lib.api.event.PlayerAttackEvent; -import net.Indyuce.mmocore.MMOCore; -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.skill.Skill; -import net.Indyuce.mmocore.api.skill.SkillResult; -import net.Indyuce.mmocore.api.util.math.formula.LinearValue; -import net.Indyuce.mmocore.api.util.math.particle.ParabolicProjectile; -import org.bukkit.*; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.scheduler.BukkitRunnable; - -public class Ambers extends Skill implements Listener { - public Ambers() { - super(); - 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(); - - addModifier("cooldown", new LinearValue(3, -.1, 1, 3)); - addModifier("percent", new LinearValue(10, .1, 10, 20)); - - Bukkit.getPluginManager().registerEvents(this, MMOCore.plugin); - } - - @EventHandler - public void a(PlayerAttackEvent event) { - PlayerData data = PlayerData.get(event.getData().getUniqueId()); - if (!event.getAttack().hasType(DamageType.SKILL) || !data.getProfess().hasSkill(this)) - return; - - SkillResult cast = data.cast(this); - if (!cast.isSuccessful()) - 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")); - } - - public static class Amber extends BukkitRunnable { - private final Location loc; - private final PlayerData data; - private final double percent; - - private int j; - - private Amber(PlayerData 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); - } - - @Override - public void run() { - if(!data.isOnline()) return; - if (j++ > 66 || !data.getPlayer().getWorld().equals(loc.getWorld())) { - cancel(); - return; - } - - if (data.getPlayer().getLocation().distanceSquared(loc) < 2) { - - 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); - - cancel(); - return; - } - - for (int j = 0; j < 5; j++) - loc.getWorld().spawnParticle(Particle.SPELL_MOB, loc, 0, 1, 0.647, 0, 1); - loc.getWorld().spawnParticle(Particle.REDSTONE, loc, 1, new Particle.DustOptions(Color.ORANGE, 1.3f)); - } - } -} diff --git a/src/main/java/net/Indyuce/mmocore/skill/Backstab.java b/src/main/java/net/Indyuce/mmocore/skill/Backstab.java deleted file mode 100644 index 7fcc8b4e..00000000 --- a/src/main/java/net/Indyuce/mmocore/skill/Backstab.java +++ /dev/null @@ -1,51 +0,0 @@ -package net.Indyuce.mmocore.skill; - -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; - -import net.Indyuce.mmocore.MMOCore; -import net.Indyuce.mmocore.api.player.PlayerData; -import net.Indyuce.mmocore.api.skill.Skill; -import net.Indyuce.mmocore.api.skill.SkillResult; -import net.Indyuce.mmocore.api.util.math.formula.LinearValue; -import io.lumine.mythic.lib.api.DamageType; -import io.lumine.mythic.lib.api.event.PlayerAttackEvent; - -public class Backstab extends Skill implements Listener { - 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 (data.isInCombat() || !event.getAttack().hasType(DamageType.WEAPON) - || event.getPlayer().getEyeLocation().getDirection().angle(target.getEyeLocation().getDirection()) > Math.PI / 6 - || !data.getProfess().hasSkill(this)) - return; - - SkillResult cast = data.cast(this); - if (!cast.isSuccessful()) - return; - - data.cast(cast.getInfo()); - event.getAttack().multiplyDamage(1 + cast.getModifier("extra") / 100); - 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/CasterMetadata.java b/src/main/java/net/Indyuce/mmocore/skill/CasterMetadata.java new file mode 100644 index 00000000..573a092b --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/skill/CasterMetadata.java @@ -0,0 +1,57 @@ +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/Combo_Attack.java b/src/main/java/net/Indyuce/mmocore/skill/Combo_Attack.java deleted file mode 100644 index 661543be..00000000 --- a/src/main/java/net/Indyuce/mmocore/skill/Combo_Attack.java +++ /dev/null @@ -1,59 +0,0 @@ -package net.Indyuce.mmocore.skill; - -import org.bukkit.Material; -import org.bukkit.Particle; -import org.bukkit.Sound; -import org.bukkit.entity.LivingEntity; -import org.bukkit.scheduler.BukkitRunnable; - -import net.Indyuce.mmocore.MMOCore; -import net.Indyuce.mmocore.api.player.PlayerData; -import net.Indyuce.mmocore.api.skill.Skill; -import net.Indyuce.mmocore.api.skill.SkillResult; -import net.Indyuce.mmocore.api.skill.result.TargetSkillResult; -import net.Indyuce.mmocore.api.util.math.formula.LinearValue; -import io.lumine.mythic.lib.MythicLib; -import io.lumine.mythic.lib.api.AttackResult; -import io.lumine.mythic.lib.api.DamageType; - -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 SkillResult whenCast(PlayerData data, SkillInfo skill) { - TargetSkillResult cast = new TargetSkillResult(data, 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(!data.isOnline()) return; - if (c++ > count) { - 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); - MythicLib.plugin.getDamage().damage(data.getPlayer(), target, new AttackResult(damage, DamageType.SKILL, DamageType.PHYSICAL)); - } - }.runTaskTimer(MMOCore.plugin, 0, 5); - return cast; - } -} diff --git a/src/main/java/net/Indyuce/mmocore/skill/Control.java b/src/main/java/net/Indyuce/mmocore/skill/Control.java deleted file mode 100644 index 6887d08f..00000000 --- a/src/main/java/net/Indyuce/mmocore/skill/Control.java +++ /dev/null @@ -1,106 +0,0 @@ -package net.Indyuce.mmocore.skill; - -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; - -import net.Indyuce.mmocore.MMOCore; -import net.Indyuce.mmocore.api.player.PlayerData; -import net.Indyuce.mmocore.api.skill.Skill; -import net.Indyuce.mmocore.api.skill.SkillResult; -import net.Indyuce.mmocore.api.skill.result.TargetSkillResult; -import net.Indyuce.mmocore.api.util.math.formula.LinearValue; -import io.lumine.mythic.lib.version.VersionMaterial; -import io.lumine.mythic.lib.version.VersionSound; - -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 SkillResult whenCast(PlayerData data, SkillInfo skill) { - TargetSkillResult cast = new TargetSkillResult(data, skill, 7); - if (!cast.isSuccessful()) - return cast; - - if(data.isOnline()) - data.getPlayer().getWorld().playSound(data.getPlayer().getLocation(), Sound.BLOCK_END_PORTAL_FRAME_FILL, 1, 1); - cast.getTarget().addPotionEffect(new PotionEffect(PotionEffectType.SLOW, 20 * 2, 0)); - new TelekinesyRunnable(data, 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 PlayerData data; - - private final double f, d; - - private int j; - - public TelekinesyRunnable(PlayerData data, LivingEntity entity, double force, double duration) { - this.entity = entity; - this.data = data; - - d = duration * 20; - f = force; - - runTaskTimer(MMOCore.plugin, 0, 1); - Bukkit.getPluginManager().registerEvents(this, MMOCore.plugin); - } - - @EventHandler - public void a(PlayerInteractEvent event) { - if(!data.isOnline()) return; - if (event.getPlayer().equals(data.getPlayer()) && event.getAction().name().contains("LEFT_CLICK")) { - Vector vec = data.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 (!data.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/Deep_Wound.java b/src/main/java/net/Indyuce/mmocore/skill/Deep_Wound.java deleted file mode 100644 index 0f338aaf..00000000 --- a/src/main/java/net/Indyuce/mmocore/skill/Deep_Wound.java +++ /dev/null @@ -1,50 +0,0 @@ -package net.Indyuce.mmocore.skill; - -import org.bukkit.Material; -import org.bukkit.Particle; -import org.bukkit.Sound; -import org.bukkit.attribute.Attribute; -import org.bukkit.entity.LivingEntity; - -import net.Indyuce.mmocore.api.player.PlayerData; -import net.Indyuce.mmocore.api.skill.Skill; -import net.Indyuce.mmocore.api.skill.SkillResult; -import net.Indyuce.mmocore.api.skill.result.TargetSkillResult; -import net.Indyuce.mmocore.api.util.math.formula.LinearValue; -import io.lumine.mythic.lib.MythicLib; -import io.lumine.mythic.lib.api.AttackResult; -import io.lumine.mythic.lib.api.DamageType; - -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 SkillResult whenCast(PlayerData data, SkillInfo skill) { - TargetSkillResult cast = new TargetSkillResult(data, skill, 3); - if (!cast.isSuccessful() || !data.isOnline()) - 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); - MythicLib.plugin.getDamage().damage(data.getPlayer(), target, new AttackResult(damage, DamageType.SKILL, DamageType.PHYSICAL)); - return cast; - } -} diff --git a/src/main/java/net/Indyuce/mmocore/skill/Empowered_Attack.java b/src/main/java/net/Indyuce/mmocore/skill/Empowered_Attack.java deleted file mode 100644 index 2c99a5e8..00000000 --- a/src/main/java/net/Indyuce/mmocore/skill/Empowered_Attack.java +++ /dev/null @@ -1,122 +0,0 @@ -package net.Indyuce.mmocore.skill; - -import io.lumine.mythic.lib.MythicLib; -import io.lumine.mythic.lib.api.AttackResult; -import io.lumine.mythic.lib.api.DamageType; -import io.lumine.mythic.lib.api.event.PlayerAttackEvent; -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.skill.Skill; -import net.Indyuce.mmocore.api.skill.SkillResult; -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 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 SkillResult whenCast(PlayerData data, SkillInfo skill) { - SkillResult cast = new SkillResult(data, skill); - if (!cast.isSuccessful()) - return cast; - - if(data.isOnline()) - data.getPlayer().playSound(data.getPlayer().getLocation(), Sound.BLOCK_END_PORTAL_FRAME_FILL, 1, 1); - new EmpoweredAttack(data, 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 PlayerData player; - private final double c, r, rad; - - public EmpoweredAttack(PlayerData player, double extra, double ratio, double radius) { - this.player = player; - this.c = 1 + extra / 100; - this.r = ratio / 100; - this.rad = radius; - - if(player.isOnline()) - new SmallParticleEffect(player.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(!player.isOnline()) return; - if (event.getPlayer().equals(player.getPlayer()) && event.getAttack().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() * r; - Location src = target.getLocation().add(0, target.getHeight() / 2, 0); - - for (Entity entity : target.getNearbyEntities(rad, rad, rad)) - if (MMOCoreUtils.canTarget(player, entity)) { - drawVector(src, entity.getLocation().add(0, entity.getHeight() / 2, 0).subtract(src).toVector()); - MythicLib.plugin.getDamage().damage(player.getPlayer(), (LivingEntity) entity, new AttackResult(sweep, DamageType.SKILL, DamageType.PHYSICAL)); - } - - /* - * apply damage afterwards otherwise the damage dealt to nearby - * entities scale with the extra ability damage. - */ - event.getAttack().multiplyDamage(1 + c); - } - } - } -} diff --git a/src/main/java/net/Indyuce/mmocore/skill/Evade.java b/src/main/java/net/Indyuce/mmocore/skill/Evade.java deleted file mode 100644 index ae88973a..00000000 --- a/src/main/java/net/Indyuce/mmocore/skill/Evade.java +++ /dev/null @@ -1,84 +0,0 @@ -package net.Indyuce.mmocore.skill; - -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; - -import net.Indyuce.mmocore.MMOCore; -import net.Indyuce.mmocore.api.player.PlayerData; -import net.Indyuce.mmocore.api.skill.Skill; -import net.Indyuce.mmocore.api.skill.SkillResult; -import net.Indyuce.mmocore.api.util.math.formula.LinearValue; -import net.Indyuce.mmocore.api.util.math.particle.SmallParticleEffect; -import io.lumine.mythic.lib.api.DamageType; -import io.lumine.mythic.lib.api.event.PlayerAttackEvent; -import io.lumine.mythic.lib.version.VersionSound; - -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 SkillResult whenCast(PlayerData data, SkillInfo skill) { - SkillResult cast = new SkillResult(data, skill); - if (!cast.isSuccessful()) - return cast; - if(data.isOnline()) { - data.getPlayer().getWorld().playSound(data.getPlayer().getLocation(), VersionSound.ENTITY_ENDERMAN_TELEPORT.toSound(), 1, 2); - new SmallParticleEffect(data.getPlayer(), Particle.CLOUD); - } - new EvadeSkill(data, 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().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/Fire_Berserker.java b/src/main/java/net/Indyuce/mmocore/skill/Fire_Berserker.java deleted file mode 100644 index fa7f81b5..00000000 --- a/src/main/java/net/Indyuce/mmocore/skill/Fire_Berserker.java +++ /dev/null @@ -1,39 +0,0 @@ -package net.Indyuce.mmocore.skill; - -import java.util.Optional; - -import org.bukkit.Bukkit; -import org.bukkit.Material; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; - -import net.Indyuce.mmocore.MMOCore; -import net.Indyuce.mmocore.api.player.PlayerData; -import net.Indyuce.mmocore.api.skill.Skill; -import net.Indyuce.mmocore.api.util.math.formula.LinearValue; -import io.lumine.mythic.lib.api.event.PlayerAttackEvent; - -public class Fire_Berserker extends Skill implements Listener { - 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().multiplyDamage(1 + skillInfo.getModifier("extra", data.getSkillLevel(this)) / 100)); - } - } -} diff --git a/src/main/java/net/Indyuce/mmocore/skill/Fire_Rage.java b/src/main/java/net/Indyuce/mmocore/skill/Fire_Rage.java deleted file mode 100644 index 53a12a29..00000000 --- a/src/main/java/net/Indyuce/mmocore/skill/Fire_Rage.java +++ /dev/null @@ -1,165 +0,0 @@ -package net.Indyuce.mmocore.skill; - -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.PotionEffect; -import org.bukkit.potion.PotionEffectType; -import org.bukkit.scheduler.BukkitRunnable; -import org.bukkit.util.Vector; - -import net.Indyuce.mmocore.MMOCore; -import net.Indyuce.mmocore.api.player.PlayerData; -import net.Indyuce.mmocore.api.skill.Skill; -import net.Indyuce.mmocore.api.skill.SkillResult; -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 io.lumine.mythic.lib.MythicLib; -import io.lumine.mythic.lib.api.AttackResult; -import io.lumine.mythic.lib.api.DamageType; -import io.lumine.mythic.lib.version.VersionMaterial; -import io.lumine.mythic.lib.version.VersionSound; - -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 SkillResult whenCast(PlayerData data, SkillInfo skill) { - SkillResult cast = new SkillResult(data, skill); - if (!cast.isSuccessful()) - return cast; - - new Rage(data, cast); - return cast; - } - - public static class Rage extends BukkitRunnable implements Listener { - private final PlayerData data; - 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(PlayerData data, SkillResult cast) { - this.data = data; - 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); - - if(data.isOnline()) { - data.getPlayer().removePotionEffect(PotionEffectType.SLOW); - data.getPlayer().addPotionEffect(new PotionEffect(PotionEffectType.SLOW, (int) (cast.getModifier("duration") * 20), 1)); - } - } - - @EventHandler - public void a(PlayerInteractEvent event) { - if(!data.isOnline()) return; - if (event.getPlayer().equals(data.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() { - if(!data.isOnline()) return; - VectorRotation rotation = new VectorRotation(data.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(data.getPlayer().getEyeLocation().getDirection().multiply(.5)).multiply(.3); - data.getPlayer().getWorld().spawnParticle(Particle.FLAME, data.getPlayer().getLocation().add(0, 1.3, 0).add(data.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(!data.isOnline()) return; - if (last) { - data.getPlayer().removePotionEffect(PotionEffectType.SLOW); - data.getPlayer().removePotionEffect(PotionEffectType.SLOW); - } - - data.getPlayer().getWorld().playSound(data.getPlayer().getLocation(), VersionSound.ENTITY_FIREWORK_ROCKET_BLAST.toSound(), 1, last ? 0 : 1); - new BukkitRunnable() { - int j = 0; - final Vector vec = data.getPlayer().getEyeLocation().getDirection(); - final Location loc = data.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(data, 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); - MythicLib.plugin.getDamage().damage(data.getPlayer(), (LivingEntity) target, new AttackResult(damage, DamageType.SKILL, DamageType.PROJECTILE, DamageType.MAGIC)); - cancel(); - } - } - }.runTaskTimer(MMOCore.plugin, 0, 1); - } - - @Override - public void run() { - if (data.getPlayer().isDead() || !data.getPlayer().isOnline()) { - close(); - return; - } - - b += Math.PI / 30; - for (int j = 0; j < c; j++) { - double a = Math.PI * 2 * j / count + b; - data.getPlayer().spawnParticle(Particle.FLAME, data.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/Fireball.java b/src/main/java/net/Indyuce/mmocore/skill/Fireball.java deleted file mode 100644 index 239ddde0..00000000 --- a/src/main/java/net/Indyuce/mmocore/skill/Fireball.java +++ /dev/null @@ -1,105 +0,0 @@ -package net.Indyuce.mmocore.skill; - -import io.lumine.mythic.lib.MythicLib; -import io.lumine.mythic.lib.api.AttackResult; -import io.lumine.mythic.lib.api.DamageType; -import io.lumine.mythic.lib.api.MMORayTraceResult; -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.skill.Skill; -import net.Indyuce.mmocore.api.skill.SkillResult; -import net.Indyuce.mmocore.api.util.MMOCoreUtils; -import net.Indyuce.mmocore.api.util.math.formula.LinearValue; -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 SkillResult whenCast(PlayerData data, SkillInfo skill) { - SkillResult cast = new SkillResult(data, skill); - if (!cast.isSuccessful() || !data.isOnline()) - return cast; - - data.getPlayer().getWorld().playSound(data.getPlayer().getLocation(), VersionSound.ENTITY_FIREWORK_ROCKET_BLAST.toSound(), 1, 1); - new BukkitRunnable() { - int j = 0; - final Vector vec = data.getPlayer().getEyeLocation().getDirection(); - final Location loc = data.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(data, 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"); - MythicLib.plugin.getDamage().damage(data.getPlayer(), (LivingEntity) target, new AttackResult(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(data, entity)); - if (result.hasHit()) - MythicLib.plugin.getDamage().damage(data.getPlayer(), result.getHit(), new AttackResult(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/Furtive_Strike.java b/src/main/java/net/Indyuce/mmocore/skill/Furtive_Strike.java deleted file mode 100644 index 613fe3ac..00000000 --- a/src/main/java/net/Indyuce/mmocore/skill/Furtive_Strike.java +++ /dev/null @@ -1,53 +0,0 @@ -package net.Indyuce.mmocore.skill; - -import org.bukkit.Material; -import org.bukkit.Particle; -import org.bukkit.Sound; -import org.bukkit.entity.LivingEntity; - -import net.Indyuce.mmocore.api.player.PlayerData; -import net.Indyuce.mmocore.api.skill.Skill; -import net.Indyuce.mmocore.api.skill.SkillResult; -import net.Indyuce.mmocore.api.skill.result.TargetSkillResult; -import net.Indyuce.mmocore.api.util.math.formula.LinearValue; -import net.Indyuce.mmocore.api.util.math.particle.SmallParticleEffect; -import io.lumine.mythic.lib.MythicLib; -import io.lumine.mythic.lib.api.AttackResult; -import io.lumine.mythic.lib.api.DamageType; - -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 SkillResult whenCast(PlayerData data, SkillInfo skill) { - TargetSkillResult cast = new TargetSkillResult(data, skill, 3); - if (!cast.isSuccessful() || !data.isOnline()) - 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(data.getPlayer()))) { - new SmallParticleEffect(target, Particle.SPELL_WITCH); - damage *= 1 + cast.getModifier("extra") / 100; - } - - MythicLib.plugin.getDamage().damage(data.getPlayer(), target, new AttackResult(damage, DamageType.SKILL, DamageType.PHYSICAL)); - return cast; - } -} diff --git a/src/main/java/net/Indyuce/mmocore/skill/Greater_Healings.java b/src/main/java/net/Indyuce/mmocore/skill/Greater_Healings.java deleted file mode 100644 index 0a2ddcb1..00000000 --- a/src/main/java/net/Indyuce/mmocore/skill/Greater_Healings.java +++ /dev/null @@ -1,42 +0,0 @@ -package net.Indyuce.mmocore.skill; - -import org.bukkit.Material; -import org.bukkit.Particle; -import org.bukkit.Sound; -import org.bukkit.attribute.Attribute; -import org.bukkit.entity.LivingEntity; - -import net.Indyuce.mmocore.api.player.PlayerData; -import net.Indyuce.mmocore.api.skill.Skill; -import net.Indyuce.mmocore.api.skill.SkillResult; -import net.Indyuce.mmocore.api.skill.result.TargetSkillResult; -import net.Indyuce.mmocore.api.util.math.formula.LinearValue; -import net.Indyuce.mmocore.api.util.math.particle.SmallParticleEffect; - -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 SkillResult whenCast(PlayerData data, SkillInfo skill) { - SkillResult cast = data.getPlayer().isSneaking() ? new SkillResult(data, skill) : new TargetSkillResult(data, skill, 50, true); - if (!cast.isSuccessful()) - return cast; - - LivingEntity target = cast instanceof TargetSkillResult ? ((TargetSkillResult) cast).getTarget() : data.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/Human_Shield.java b/src/main/java/net/Indyuce/mmocore/skill/Human_Shield.java deleted file mode 100644 index 380459fd..00000000 --- a/src/main/java/net/Indyuce/mmocore/skill/Human_Shield.java +++ /dev/null @@ -1,105 +0,0 @@ -package net.Indyuce.mmocore.skill; - -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; - -import net.Indyuce.mmocore.MMOCore; -import net.Indyuce.mmocore.api.player.PlayerData; -import net.Indyuce.mmocore.api.skill.Skill; -import net.Indyuce.mmocore.api.skill.SkillResult; -import net.Indyuce.mmocore.api.skill.result.TargetSkillResult; -import net.Indyuce.mmocore.api.util.math.formula.LinearValue; -import io.lumine.mythic.lib.version.VersionMaterial; - -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 SkillResult whenCast(PlayerData data, SkillInfo skill) { - TargetSkillResult cast = new TargetSkillResult(data, skill, 7, true); - if (!cast.isSuccessful()) - return cast; - - if (!(cast.getTarget() instanceof Player)) { - cast.abort(); - return cast; - } - - data.getPlayer().getWorld().playSound(data.getPlayer().getLocation(), Sound.ENTITY_BLAZE_AMBIENT, 1, 1); - new HumanShield(data, (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/Ice_Spikes.java b/src/main/java/net/Indyuce/mmocore/skill/Ice_Spikes.java deleted file mode 100644 index ff28852f..00000000 --- a/src/main/java/net/Indyuce/mmocore/skill/Ice_Spikes.java +++ /dev/null @@ -1,80 +0,0 @@ -package net.Indyuce.mmocore.skill; - -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; - -import net.Indyuce.mmocore.MMOCore; -import net.Indyuce.mmocore.api.player.PlayerData; -import net.Indyuce.mmocore.api.skill.Skill; -import net.Indyuce.mmocore.api.skill.SkillResult; -import net.Indyuce.mmocore.api.skill.result.LocationSkillResult; -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 io.lumine.mythic.lib.MythicLib; -import io.lumine.mythic.lib.api.AttackResult; -import io.lumine.mythic.lib.api.DamageType; -import io.lumine.mythic.lib.version.VersionMaterial; - -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 SkillResult whenCast(PlayerData data, SkillInfo skill) { - LocationSkillResult cast = new LocationSkillResult(data, skill, 20); - if (!cast.isSuccessful() || !data.isOnline()) - 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(data, entity)) { - MythicLib.plugin.getDamage().damage(data.getPlayer(), (LivingEntity) entity, new AttackResult(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/Minor_Healings.java b/src/main/java/net/Indyuce/mmocore/skill/Minor_Healings.java deleted file mode 100644 index 44f23cbc..00000000 --- a/src/main/java/net/Indyuce/mmocore/skill/Minor_Healings.java +++ /dev/null @@ -1,42 +0,0 @@ -package net.Indyuce.mmocore.skill; - -import org.bukkit.Material; -import org.bukkit.Particle; -import org.bukkit.Sound; -import org.bukkit.attribute.Attribute; -import org.bukkit.entity.LivingEntity; - -import net.Indyuce.mmocore.api.player.PlayerData; -import net.Indyuce.mmocore.api.skill.Skill; -import net.Indyuce.mmocore.api.skill.SkillResult; -import net.Indyuce.mmocore.api.skill.result.TargetSkillResult; -import net.Indyuce.mmocore.api.util.math.formula.LinearValue; -import net.Indyuce.mmocore.api.util.math.particle.SmallParticleEffect; - -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 SkillResult whenCast(PlayerData data, SkillInfo skill) { - SkillResult cast = data.getPlayer().isSneaking() ? new SkillResult(data, skill) : new TargetSkillResult(data, skill, 50, true); - if (!cast.isSuccessful()) - return cast; - - LivingEntity target = cast instanceof TargetSkillResult ? ((TargetSkillResult) cast).getTarget() : data.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/PassiveSkill.java b/src/main/java/net/Indyuce/mmocore/skill/PassiveSkill.java new file mode 100644 index 00000000..acb7894b --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/skill/PassiveSkill.java @@ -0,0 +1,19 @@ +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/api/skill/PlayerSkillData.java b/src/main/java/net/Indyuce/mmocore/skill/PlayerSkillData.java similarity index 50% rename from src/main/java/net/Indyuce/mmocore/api/skill/PlayerSkillData.java rename to src/main/java/net/Indyuce/mmocore/skill/PlayerSkillData.java index 6e6afce4..ed08851a 100644 --- a/src/main/java/net/Indyuce/mmocore/api/skill/PlayerSkillData.java +++ b/src/main/java/net/Indyuce/mmocore/skill/PlayerSkillData.java @@ -1,11 +1,13 @@ -package net.Indyuce.mmocore.api.skill; +package net.Indyuce.mmocore.skill; import java.util.HashMap; import java.util.Map; +import io.lumine.mythic.utils.cooldown.CooldownMap; import net.Indyuce.mmocore.api.player.PlayerData; -import net.Indyuce.mmocore.api.skill.Skill.SkillInfo; +import net.Indyuce.mmocore.skill.Skill.SkillInfo; import net.Indyuce.mmocore.comp.mythicmobs.skill.MythicMobSkill; +import net.Indyuce.mmocore.skill.metadata.SkillMetadata; /** * Note: any method which return longs returns milliseconds. @@ -16,15 +18,6 @@ public class PlayerSkillData { private final Map cooldowns = new HashMap<>(); private final PlayerData data; - /** - * MythicMobs skill damage is handled via math formula which can retrieve - * PAPI placeholders. When a skill is cast, all skill modifiers are cached - * into that map: 1- for easier and faster access 2- it removes interference - * for example when stats are calculating not when the spell is cast but - * rather when the spell hits - */ - private final Map cache = new HashMap<>(); - public PlayerSkillData(PlayerData data) { this.data = data; } @@ -82,66 +75,4 @@ public class PlayerSkillData { long reduction = (long) (relative ? value * (double) getCooldown(skill) : value * 1000.); cooldowns.put(skill.getSkill().getId(), lastCast(skill.getSkill()) + reduction); } - - public double getCachedModifier(String name) { - return cache.containsKey(name) ? cache.get(name).getValue() : 0; - } - - public void cacheModifiers(MythicMobSkill skill, SkillResult cast) { - cacheModifiers(skill.getInternalName(), cast); - } - - /** - * Caches all modifiers from a cast skill in the map - * - * @param skill - * Skill identifier being used as reference in the map - * @param cast - * Skill being cast - */ - public void cacheModifiers(String skill, SkillResult cast) { - for (String modifier : cast.getSkill().getModifiers()) - cacheModifier(skill, modifier, cast.getModifier(modifier)); - - cacheModifier(skill, "level", cast.getLevel()); - } - - /** - * Caches a specific modifier - * - * @param skill - * The identifier of the skill being cast - * @param name - * Modifier name - * @param value - * Modifier value - */ - public void cacheModifier(String skill, String name, double value) { - cache.put(skill + "." + name, new CachedModifier(value)); - } - - /** - * Empties cached modifiers. Modifiers should time out one minute after the - * skill was cast - */ - public void refresh() { - cache.values().removeIf(CachedModifier::isTimedOut); - } - - public static class CachedModifier { - private final long date = System.currentTimeMillis(); - private final double value; - - public CachedModifier(double value) { - this.value = value; - } - - public boolean isTimedOut() { - return date + 1000 * 60 < System.currentTimeMillis(); - } - - public double getValue() { - return value; - } - } } diff --git a/src/main/java/net/Indyuce/mmocore/skill/Power_Mark.java b/src/main/java/net/Indyuce/mmocore/skill/Power_Mark.java deleted file mode 100644 index affa38d6..00000000 --- a/src/main/java/net/Indyuce/mmocore/skill/Power_Mark.java +++ /dev/null @@ -1,139 +0,0 @@ -package net.Indyuce.mmocore.skill; - -import org.bukkit.Bukkit; -import org.bukkit.Color; -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.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; - -import net.Indyuce.mmocore.MMOCore; -import net.Indyuce.mmocore.api.player.PlayerData; -import net.Indyuce.mmocore.api.skill.Skill; -import net.Indyuce.mmocore.api.skill.SkillResult; -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 io.lumine.mythic.lib.MythicLib; -import io.lumine.mythic.lib.api.AttackResult; -import io.lumine.mythic.lib.api.DamageType; -import io.lumine.mythic.lib.api.event.PlayerAttackEvent; -import io.lumine.mythic.lib.version.VersionMaterial; -import io.lumine.mythic.lib.version.VersionSound; - -public class Power_Mark extends Skill implements Listener { - 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().hasType(DamageType.WEAPON) || !data.getProfess().hasSkill(this)) - return; - - SkillResult cast = data.cast(this); - if (!cast.isSuccessful()) - return; - - new PowerMark(data, cast, event.getEntity().getLocation()); - } - - public class PowerMark extends BukkitRunnable implements Listener { - private final PlayerData data; - private final Location loc; - - private final double duration; - private final double ratio; - private double stun; - - private double accumulate; - private int j; - - public PowerMark(PlayerData data, SkillResult cast, Location loc) { - this.data = data; - 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()) && PlayerData.get(event.getData().getUniqueId()).equals(data)) { - accumulate += event.getAttack().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(!data.isOnline()) return; - 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(data, entity)) { - ((LivingEntity) entity).addPotionEffect(new PotionEffect(PotionEffectType.SLOW, (int) (stun * 20), 10, false, false)); - MythicLib.plugin.getDamage().damage(data.getPlayer(), (LivingEntity) entity, new AttackResult(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/api/skill/Skill.java b/src/main/java/net/Indyuce/mmocore/skill/Skill.java similarity index 96% rename from src/main/java/net/Indyuce/mmocore/api/skill/Skill.java rename to src/main/java/net/Indyuce/mmocore/skill/Skill.java index 796386ed..b2f46550 100644 --- a/src/main/java/net/Indyuce/mmocore/api/skill/Skill.java +++ b/src/main/java/net/Indyuce/mmocore/skill/Skill.java @@ -1,9 +1,10 @@ -package net.Indyuce.mmocore.api.skill; +package net.Indyuce.mmocore.skill; 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; @@ -133,12 +134,7 @@ public abstract class Skill { return current instanceof IntegerLinearValue ? new IntegerLinearValue(config) : new LinearValue(config); } - /* - * not overriden for passive skills therefore not abstract. - */ - public SkillResult whenCast(PlayerData data, SkillInfo skill) { - return new SkillResult(data, skill); - } + public abstract SkillMetadata whenCast(CasterMetadata casterMeta, SkillInfo skill); public SkillInfo newSkillInfo(ConfigurationSection config) { return new SkillInfo(config); diff --git a/src/main/java/net/Indyuce/mmocore/skill/Sneaky_Picky.java b/src/main/java/net/Indyuce/mmocore/skill/Sneaky_Picky.java deleted file mode 100644 index 39c9cea5..00000000 --- a/src/main/java/net/Indyuce/mmocore/skill/Sneaky_Picky.java +++ /dev/null @@ -1,50 +0,0 @@ -package net.Indyuce.mmocore.skill; - -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; - -import net.Indyuce.mmocore.MMOCore; -import net.Indyuce.mmocore.api.player.PlayerData; -import net.Indyuce.mmocore.api.skill.Skill; -import net.Indyuce.mmocore.api.skill.SkillResult; -import net.Indyuce.mmocore.api.util.math.formula.LinearValue; -import io.lumine.mythic.lib.api.DamageType; -import io.lumine.mythic.lib.api.event.PlayerAttackEvent; - -public class Sneaky_Picky extends Skill 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(); - - 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()); - if (!event.getAttack().hasType(DamageType.WEAPON) || data.isInCombat() || !data.getProfess().hasSkill(this)) - return; - - SkillResult cast = data.cast(this); - if (!cast.isSuccessful()) - return; - - data.cast(cast.getInfo()); - - event.getAttack().multiplyDamage(1 + cast.getModifier("extra") / 100); - 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); - } -} diff --git a/src/main/java/net/Indyuce/mmocore/skill/Telekinesy.java b/src/main/java/net/Indyuce/mmocore/skill/Telekinesy.java deleted file mode 100644 index 476f47ca..00000000 --- a/src/main/java/net/Indyuce/mmocore/skill/Telekinesy.java +++ /dev/null @@ -1,99 +0,0 @@ -package net.Indyuce.mmocore.skill; - -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; - -import net.Indyuce.mmocore.MMOCore; -import net.Indyuce.mmocore.api.player.PlayerData; -import net.Indyuce.mmocore.api.skill.Skill; -import net.Indyuce.mmocore.api.skill.SkillResult; -import net.Indyuce.mmocore.api.skill.result.TargetSkillResult; -import net.Indyuce.mmocore.api.util.math.formula.LinearValue; -import net.Indyuce.mmocore.api.util.math.particle.ParabolicProjectile; -import io.lumine.mythic.lib.version.VersionMaterial; -import io.lumine.mythic.lib.version.VersionSound; - -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 SkillResult whenCast(PlayerData data, SkillInfo skill) { - TargetSkillResult cast = new TargetSkillResult(data, skill, 7); - if (!cast.isSuccessful() || !data.isOnline()) - return cast; - - data.getPlayer().getWorld().playSound(data.getPlayer().getLocation(), Sound.BLOCK_END_PORTAL_FRAME_FILL, 1, 1); - new TelekinesyRunnable(data, 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(!data.isOnline()) return; - 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/Warp.java b/src/main/java/net/Indyuce/mmocore/skill/Warp.java deleted file mode 100644 index 4ec1b82d..00000000 --- a/src/main/java/net/Indyuce/mmocore/skill/Warp.java +++ /dev/null @@ -1,60 +0,0 @@ -package net.Indyuce.mmocore.skill; - -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.Particle; -import org.bukkit.Sound; -import org.bukkit.block.Block; - -import net.Indyuce.mmocore.api.player.PlayerData; -import net.Indyuce.mmocore.api.skill.Skill; -import net.Indyuce.mmocore.api.skill.SkillResult; -import net.Indyuce.mmocore.api.util.math.formula.LinearValue; -import net.Indyuce.mmocore.api.util.math.particle.ParabolicProjectile; -import io.lumine.mythic.lib.version.VersionSound; - -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 SkillResult whenCast(PlayerData data, SkillInfo skill) { - WarpCast cast = new WarpCast(data, skill); - if (!cast.isSuccessful() || !data.isOnline()) - return cast; - - data.getPlayer().getWorld().playSound(data.getPlayer().getLocation(), Sound.BLOCK_END_PORTAL_FRAME_FILL, 1, 2); - - Location loc = cast.block.getLocation().add(0, 1, 0); - loc.setYaw(data.getPlayer().getLocation().getYaw()); - loc.setPitch(data.getPlayer().getLocation().getPitch()); - - new ParabolicProjectile(data.getPlayer().getLocation().add(0, 1, 0), loc.clone().add(0, 1, 0), () -> { - if (data.getPlayer().isOnline() && !data.getPlayer().isDead()) { - data.getPlayer().teleport(loc); - data.getPlayer().getWorld().spawnParticle(Particle.EXPLOSION_LARGE, data.getPlayer().getLocation().add(0, 1, 0), 0); - data.getPlayer().getWorld().spawnParticle(Particle.SPELL_INSTANT, data.getPlayer().getLocation().add(0, 1, 0), 32, 0, 0, 0, .1); - data.getPlayer().getWorld().playSound(data.getPlayer().getLocation(), VersionSound.ENTITY_ENDERMAN_TELEPORT.toSound(), 1, 1); - } - }, 2, Particle.SPELL_INSTANT); - return cast; - } - - private class WarpCast extends SkillResult { - private Block block; - - public WarpCast(PlayerData data, SkillInfo skill) { - super(data, skill); - if(!data.isOnline()) abort(); - else if (isSuccessful() && (block = data.getPlayer().getTargetBlock(null, (int) getModifier("range"))) == null) - abort(); - } - } -} diff --git a/src/main/java/net/Indyuce/mmocore/skill/Weaken.java b/src/main/java/net/Indyuce/mmocore/skill/Weaken.java deleted file mode 100644 index e2a42cc9..00000000 --- a/src/main/java/net/Indyuce/mmocore/skill/Weaken.java +++ /dev/null @@ -1,77 +0,0 @@ -package net.Indyuce.mmocore.skill; - -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; - -import net.Indyuce.mmocore.MMOCore; -import net.Indyuce.mmocore.api.player.PlayerData; -import net.Indyuce.mmocore.api.skill.Skill; -import net.Indyuce.mmocore.api.skill.SkillResult; -import net.Indyuce.mmocore.api.skill.result.TargetSkillResult; -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 io.lumine.mythic.lib.version.VersionMaterial; - -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 SkillResult whenCast(PlayerData data, SkillInfo skill) { - TargetSkillResult cast = new TargetSkillResult(data, skill, 7); - if (!cast.isSuccessful() || !data.isOnline()) - return cast; - - LivingEntity target = cast.getTarget(); - new ParabolicProjectile(data.getPlayer().getLocation().add(0, 1, 0), target.getLocation().add(0, target.getHeight() / 2, 0), randomVector(data.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/list/Ambers.java b/src/main/java/net/Indyuce/mmocore/skill/list/Ambers.java new file mode 100644 index 00000000..dcc8dd75 --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/skill/list/Ambers.java @@ -0,0 +1,88 @@ +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.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.event.EventHandler; +import org.bukkit.scheduler.BukkitRunnable; + +public class Ambers extends PassiveSkill { + public Ambers() { + super(); + + 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(); + + addModifier("cooldown", new LinearValue(3, -.1, 1, 3)); + addModifier("percent", new LinearValue(10, .1, 10, 20)); + + 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.SKILL) || !data.getProfess().hasSkill(this)) + return; + + SkillMetadata cast = data.cast(this); + if (!cast.isSuccessful()) + 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")); + } + + public static class Amber extends BukkitRunnable { + private final Location loc; + private final PlayerData data; + private final double percent; + + private int j; + + private Amber(PlayerData 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); + } + + @Override + public void run() { + if (!data.isOnline()) return; + if (j++ > 66 || !data.getPlayer().getWorld().equals(loc.getWorld())) { + cancel(); + return; + } + + if (data.getPlayer().getLocation().distanceSquared(loc) < 2) { + + 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); + + cancel(); + return; + } + + for (int j = 0; j < 5; j++) + loc.getWorld().spawnParticle(Particle.SPELL_MOB, loc, 0, 1, 0.647, 0, 1); + loc.getWorld().spawnParticle(Particle.REDSTONE, loc, 1, new Particle.DustOptions(Color.ORANGE, 1.3f)); + } + } +} diff --git a/src/main/java/net/Indyuce/mmocore/skill/list/Backstab.java b/src/main/java/net/Indyuce/mmocore/skill/list/Backstab.java new file mode 100644 index 00000000..e83d0844 --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/skill/list/Backstab.java @@ -0,0 +1,50 @@ +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 (data.isInCombat() || !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 new file mode 100644 index 00000000..e9f363c1 --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/skill/list/Combo_Attack.java @@ -0,0 +1,56 @@ +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 new file mode 100644 index 00000000..6c9ea03e --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/skill/list/Control.java @@ -0,0 +1,103 @@ +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 new file mode 100644 index 00000000..830ad7a2 --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/skill/list/Deep_Wound.java @@ -0,0 +1,47 @@ +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 new file mode 100644 index 00000000..fac43136 --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/skill/list/Empowered_Attack.java @@ -0,0 +1,119 @@ +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 new file mode 100644 index 00000000..13fabe1e --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/skill/list/Evade.java @@ -0,0 +1,83 @@ +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 new file mode 100644 index 00000000..bd95574f --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/skill/list/Fire_Berserker.java @@ -0,0 +1,37 @@ +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 new file mode 100644 index 00000000..ca3e5b66 --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/skill/list/Fire_Rage.java @@ -0,0 +1,158 @@ +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/Fire_Storm.java b/src/main/java/net/Indyuce/mmocore/skill/list/Fire_Storm.java similarity index 61% rename from src/main/java/net/Indyuce/mmocore/skill/Fire_Storm.java rename to src/main/java/net/Indyuce/mmocore/skill/list/Fire_Storm.java index 4a704208..000c3c76 100644 --- a/src/main/java/net/Indyuce/mmocore/skill/Fire_Storm.java +++ b/src/main/java/net/Indyuce/mmocore/skill/list/Fire_Storm.java @@ -1,5 +1,6 @@ -package net.Indyuce.mmocore.skill; +package net.Indyuce.mmocore.skill.list; +import net.Indyuce.mmocore.skill.CasterMetadata; import org.bukkit.Material; import org.bukkit.Particle; import org.bukkit.Sound; @@ -10,14 +11,14 @@ import org.bukkit.util.Vector; import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.api.player.PlayerData; -import net.Indyuce.mmocore.api.skill.Skill; -import net.Indyuce.mmocore.api.skill.SkillResult; -import net.Indyuce.mmocore.api.skill.result.TargetSkillResult; +import net.Indyuce.mmocore.skill.Skill; +import net.Indyuce.mmocore.skill.metadata.SkillMetadata; +import net.Indyuce.mmocore.skill.metadata.TargetSkillMetadata; import net.Indyuce.mmocore.api.util.math.formula.LinearValue; import net.Indyuce.mmocore.api.util.math.particle.ParabolicProjectile; import io.lumine.mythic.lib.MythicLib; import io.lumine.mythic.lib.api.AttackResult; -import io.lumine.mythic.lib.api.DamageType; +import io.lumine.mythic.lib.damage.DamageType;; import io.lumine.mythic.lib.version.VersionSound; public class Fire_Storm extends Skill { @@ -33,34 +34,34 @@ public class Fire_Storm extends Skill { } @Override - public SkillResult whenCast(PlayerData data, SkillInfo skill) { - TargetSkillResult cast = new TargetSkillResult(data, skill, 20); - if (!cast.isSuccessful() || !data.isOnline()) + public SkillMetadata whenCast(CasterMetadata caster, SkillInfo skill) { + TargetSkillMetadata cast = new TargetSkillMetadata(caster, skill, 20); + if (!cast.isSuccessful() ) return cast; LivingEntity target = cast.getTarget(); - double damage = cast.getModifier("damage"); - int ignite = (int) (20 * cast.getModifier("ignite")); + final double damage = cast.getModifier("damage"); + final int ignite = (int) (20 * cast.getModifier("ignite")); - data.getPlayer().getWorld().playSound(data.getPlayer().getLocation(), VersionSound.ENTITY_FIREWORK_ROCKET_BLAST.toSound(), 1, 1); + 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 || data.getPlayer().isDead() || !data.getPlayer().isOnline() || target.isDead() || !data.getPlayer().getWorld().equals(target.getWorld())) { + if (j++ > 5 || caster.getPlayer().isDead() || !caster.getPlayer().isOnline() || target.isDead() || !caster.getPlayer().getWorld().equals(target.getWorld())) { cancel(); return; } // TODO dynamic target location - data.getPlayer().getWorld().playSound(data.getPlayer().getLocation(), Sound.BLOCK_FIRE_AMBIENT, 1, 1); - new ParabolicProjectile(data.getPlayer().getLocation().add(0, 1, 0), target.getLocation().add(0, target.getHeight() / 2, 0), randomVector(data.getPlayer()), () -> { + 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); - MythicLib.plugin.getDamage().damage(data.getPlayer(), target, new AttackResult(damage, DamageType.SKILL, DamageType.PROJECTILE, DamageType.MAGIC)); + caster.attack(target, damage, DamageType.SKILL, DamageType.PROJECTILE, DamageType.MAGIC); target.setFireTicks(ignite); }, 2, Particle.FLAME); diff --git a/src/main/java/net/Indyuce/mmocore/skill/list/Fireball.java b/src/main/java/net/Indyuce/mmocore/skill/list/Fireball.java new file mode 100644 index 00000000..bf797a17 --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/skill/list/Fireball.java @@ -0,0 +1,104 @@ +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 new file mode 100644 index 00000000..9384b224 --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/skill/list/Furtive_Strike.java @@ -0,0 +1,50 @@ +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 new file mode 100644 index 00000000..5cb3aa3b --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/skill/list/Greater_Healings.java @@ -0,0 +1,41 @@ +package net.Indyuce.mmocore.skill.list; + +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, true); + 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 new file mode 100644 index 00000000..4e06d3ad --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/skill/list/Human_Shield.java @@ -0,0 +1,105 @@ +package net.Indyuce.mmocore.skill.list; + +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, true); + 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 new file mode 100644 index 00000000..3f48f22d --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/skill/list/Ice_Spikes.java @@ -0,0 +1,79 @@ +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 new file mode 100644 index 00000000..eff1814d --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/skill/list/Minor_Healings.java @@ -0,0 +1,41 @@ +package net.Indyuce.mmocore.skill.list; + +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, true); + 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/Neptune_Gift.java b/src/main/java/net/Indyuce/mmocore/skill/list/Neptune_Gift.java similarity index 87% rename from src/main/java/net/Indyuce/mmocore/skill/Neptune_Gift.java rename to src/main/java/net/Indyuce/mmocore/skill/list/Neptune_Gift.java index e995f95f..0e36614a 100644 --- a/src/main/java/net/Indyuce/mmocore/skill/Neptune_Gift.java +++ b/src/main/java/net/Indyuce/mmocore/skill/list/Neptune_Gift.java @@ -1,7 +1,8 @@ -package net.Indyuce.mmocore.skill; +package net.Indyuce.mmocore.skill.list; import java.util.Optional; +import net.Indyuce.mmocore.skill.PassiveSkill; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.event.EventHandler; @@ -10,11 +11,11 @@ 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.api.skill.Skill; +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 Skill implements Listener { +public class Neptune_Gift extends PassiveSkill { public Neptune_Gift() { super("NEPTUNE_GIFT"); setName("Neptune's Gift"); 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 new file mode 100644 index 00000000..ec235df6 --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/skill/list/Power_Mark.java @@ -0,0 +1,134 @@ +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 new file mode 100644 index 00000000..96b33915 --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/skill/list/Sneaky_Picky.java @@ -0,0 +1,48 @@ +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 Sneaky_Picky extends PassiveSkill { + 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(); + + 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()); + if (!event.getAttack().getDamage().hasType(DamageType.WEAPON) || data.isInCombat() || !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.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); + } +} diff --git a/src/main/java/net/Indyuce/mmocore/skill/list/Telekinesy.java b/src/main/java/net/Indyuce/mmocore/skill/list/Telekinesy.java new file mode 100644 index 00000000..e88933c4 --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/skill/list/Telekinesy.java @@ -0,0 +1,98 @@ +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 new file mode 100644 index 00000000..fda98891 --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/skill/list/Warp.java @@ -0,0 +1,59 @@ +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 new file mode 100644 index 00000000..95688765 --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/skill/list/Weaken.java @@ -0,0 +1,76 @@ +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 new file mode 100644 index 00000000..d88cdeb1 --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/skill/metadata/LocationSkillMetadata.java @@ -0,0 +1,51 @@ +package net.Indyuce.mmocore.skill.metadata; + +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, false); + } + + /** + * @param caster Player casting the skill + * @param skill Skill being cast + * @param range Skill raycast range + * @param buff If the skill is a buff ie if it can be cast on party members + */ + public LocationSkillMetadata(CasterMetadata caster, SkillInfo skill, double range, boolean buff) { + 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, buff)); + 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 new file mode 100644 index 00000000..31607ff7 --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/skill/metadata/SkillMetadata.java @@ -0,0 +1,123 @@ +package net.Indyuce.mmocore.skill.metadata; + +import net.Indyuce.mmocore.MMOCore; +import net.Indyuce.mmocore.api.player.PlayerData; +import net.Indyuce.mmocore.comp.flags.FlagPlugin.CustomFlag; +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 { + 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") ? data.getSkillData().getCooldown(skill) : 0); + mana = (skill.getSkill().hasModifier("mana") ? skill.getModifier("mana", level) : 0); + stamina = (skill.getSkill().hasModifier("stamina") ? skill.getModifier("stamina", level) : 0); + cancelReason = !data.hasSkillUnlocked(skill) ? CancelReason.LOCKED + : cooldown > 0 ? CancelReason.COOLDOWN + : mana > data.getMana() ? CancelReason.MANA + : stamina > data.getStamina() ? CancelReason.STAMINA + : !data.isOnline() ? CancelReason.OTHER + : !MMOCore.plugin.flagPlugin.isFlagAllowed(data.getPlayer(), CustomFlag.SKILLS) ? 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") ? data.getSkillData().getCooldown(skill) : 0; + mana = skill.getSkill().hasModifier("mana") ? skill.getModifier("mana", level) : 0; + stamina = (skill.getSkill().hasModifier("stamina") ? skill.getModifier("stamina", level) : 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"); + } + + 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 + */ + 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 new file mode 100644 index 00000000..134e2917 --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/skill/metadata/TargetSkillMetadata.java @@ -0,0 +1,43 @@ +package net.Indyuce.mmocore.skill.metadata; + +import io.lumine.mythic.lib.MythicLib; +import io.lumine.mythic.lib.api.MMORayTraceResult; +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, false); + } + + /** + * @param caster Player casting the skill + * @param skill Skill being cast + * @param range Skill raycast range + * @param buff If the skill is a buff ie if it can be cast on party members + */ + public TargetSkillMetadata(CasterMetadata caster, SkillInfo skill, double range, boolean buff) { + super(caster, skill); + + if (isSuccessful()) { + MMORayTraceResult result = MythicLib.plugin.getVersion().getWrapper().rayTrace(caster.getPlayer(), range, entity -> MMOCoreUtils.canTarget(caster.getPlayerData(), entity, buff)); + if (!result.hasHit()) + abort(); + else + target = result.getHit(); + } + } + + public LivingEntity getTarget() { + return target; + } +} diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 02b54056..2f33ef1c 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -45,14 +45,14 @@ default-playerdata: # The list of all conditions which must be met for the # BLOCK REGEN and BLOCK RESTRICTIONS to apply. Set to # 'custom-mine-conditions: []' to disable custom mining entirely. -custom-mine-conditions: -- 'world{name="world,world_nether,world_the_end"}' -- 'region{name="example_region,example_region2,__global__"}' # # custom-mine-conditions: # - 'world{name="__global__"}' # # ^ will enable custom mining server wide +custom-mine-conditions: + - 'world{name="world,world_nether,world_the_end"}' + - 'region{name="example_region,example_region2,__global__"}' # Set to true to prevent vanilla blocks from being # broken when custom mining conditions are met @@ -121,14 +121,17 @@ vanilla-exp-redirection: # Requires a SERVER reload when changed. override-vanilla-exp: true +# Check the target player's RPG profile when shift when shift right clicking. +shift-click-player-profile-check: true + # If main class experience holograms should be displayed # whenever a player earns main class exp -display-main-class-exp-holograms: true +display-main-class-exp-holograms: true # Requires a SERVER reload when changed. death-exp-loss: enabled: false - + # Percentage of current EXP you lose when dying. percent: 30