From 7cabb2398a7d79c2184672d90d86b328d77dac50 Mon Sep 17 00:00:00 2001 From: Jules Date: Mon, 21 Oct 2024 21:16:07 +0200 Subject: [PATCH 1/6] Fixed %mmocore_cast_slot_offset% --- .../comp/placeholder/RPGPlaceholders.java | 34 ++++++++++++------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/comp/placeholder/RPGPlaceholders.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/comp/placeholder/RPGPlaceholders.java index e5dbc924..4f4417dc 100644 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/comp/placeholder/RPGPlaceholders.java +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/comp/placeholder/RPGPlaceholders.java @@ -15,6 +15,7 @@ import net.Indyuce.mmocore.party.AbstractParty; import net.Indyuce.mmocore.skill.CastableSkill; import net.Indyuce.mmocore.skill.ClassSkill; import net.Indyuce.mmocore.skill.RegisteredSkill; +import net.Indyuce.mmocore.skill.binding.BoundSkillInfo; import org.apache.commons.lang.Validate; import org.bukkit.Bukkit; import org.bukkit.ChatColor; @@ -25,6 +26,7 @@ import org.bukkit.entity.Player; import javax.annotation.Nullable; import java.util.Objects; import java.util.UUID; +import java.util.concurrent.atomic.AtomicInteger; public class RPGPlaceholders extends PlaceholderExpansion { @@ -102,20 +104,14 @@ public class RPGPlaceholders extends PlaceholderExpansion { final CastableSkill castable = playerData.getProfess().getSkill(skill).toCastable(playerData); final double value = playerData.getMMOPlayerData().getSkillModifierMap().calculateValue(castable, parameterId); return MythicLib.plugin.getMMOConfig().decimal.format(value); - } - - else if (identifier.startsWith("attribute_points_spent_")) { + } else if (identifier.startsWith("attribute_points_spent_")) { final String attributeId = identifier.substring(23); final PlayerAttributes.AttributeInstance attributeInstance = Objects.requireNonNull(playerData.getAttributes().getInstance(attributeId), "Could not find attribute with ID '" + attributeId + "'"); return String.valueOf(attributeInstance.getBase()); - } - - else if (identifier.equals("level_percent")) { + } else if (identifier.equals("level_percent")) { double current = playerData.getExperience(), next = playerData.getLevelUpExperience(); return MythicLib.plugin.getMMOConfig().decimal.format(current / next * 100); - } - - else if (identifier.equals("health")) + } else if (identifier.equals("health")) return StatManager.format("MAX_HEALTH", player.getPlayer().getHealth()); else if (identifier.equals("max_health")) @@ -155,19 +151,31 @@ public class RPGPlaceholders extends PlaceholderExpansion { else if (identifier.startsWith("since_last_hit")) return playerData.isInCombat() ? MythicLib.plugin.getMMOConfig().decimal.format((System.currentTimeMillis() - playerData.getCombat().getLastHit()) / 1000.) : "-1"; - // Returns the bound skill ID + // Returns the bound skill ID else if (identifier.startsWith("id_bound_")) { final int slot = Math.max(1, Integer.parseInt(identifier.substring(9))); final ClassSkill info = playerData.getBoundSkill(slot); return info == null ? "" : info.getSkill().getHandler().getId(); } - // Returns the casting slot taking into account the skill slot offset + // Returns the key that needs to be pressed to cast slot in slot N else if (identifier.startsWith("cast_slot_offset_")) { final Player online = player.getPlayer(); Validate.notNull(online, "Player is offline"); - final int slot = Integer.parseInt(identifier.substring(17)); - return String.valueOf(slot + (online.getInventory().getHeldItemSlot() < slot ? 1 : 0)); + final AtomicInteger query = new AtomicInteger(Integer.parseInt(identifier.substring(17))); + + BoundSkillInfo bound = playerData.getBoundSkills().get(query.get()); + if (bound == null || bound.isPassive()) return String.valueOf(0); + + // Offset due to passive skills + playerData.getBoundSkills().forEach((slot, skill) -> { + if (skill.isPassive() && slot < query.get()) + query.addAndGet(-1); + }); + + // Offset due to player's hotbar location + if (online.getInventory().getHeldItemSlot() < query.get()) query.addAndGet(1); + return String.valueOf(query.get()); } // Is there a passive skill bound to given slot From c84e52a963714e881671bd89eb2a30e5d7bb2d3e Mon Sep 17 00:00:00 2001 From: Jules Date: Tue, 22 Oct 2024 14:42:51 +0200 Subject: [PATCH 2/6] Fixed an issue with default skill 'Ambers' in 1.20.5+ --- .../Indyuce/mmocore/skill/list/Ambers.java | 33 +++++++++++++------ 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/list/Ambers.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/list/Ambers.java index d1248f1c..e797d3e7 100644 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/list/Ambers.java +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/list/Ambers.java @@ -9,8 +9,10 @@ import io.lumine.mythic.lib.skill.SkillMetadata; import io.lumine.mythic.lib.skill.handler.SkillHandler; import io.lumine.mythic.lib.skill.result.def.SimpleSkillResult; import io.lumine.mythic.lib.skill.trigger.TriggerMetadata; +import io.lumine.mythic.lib.skill.trigger.TriggerType; import io.lumine.mythic.lib.util.EntityLocationType; import io.lumine.mythic.lib.util.ParabolicProjectile; +import io.lumine.mythic.lib.util.annotation.BackwardsCompatibility; import io.lumine.mythic.lib.version.VParticle; import net.Indyuce.mmocore.api.event.PlayerResourceUpdateEvent; import net.Indyuce.mmocore.api.player.PlayerData; @@ -22,17 +24,25 @@ import org.bukkit.entity.LivingEntity; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.scheduler.BukkitRunnable; +import org.jetbrains.annotations.NotNull; public class Ambers extends SkillHandler implements Listener { + + @BackwardsCompatibility(version = "1.20.5") + private final boolean legacyParticles = MythicLib.plugin.getVersion().isUnder(1, 20, 5); + public Ambers() { super(false); registerModifiers("percent"); } + @NotNull @Override public SimpleSkillResult getResult(SkillMetadata meta) { - return new SimpleSkillResult(meta.hasAttackBound() && meta.hasTargetEntity() && meta.getTargetEntityOrNull() instanceof LivingEntity); + return new SimpleSkillResult(meta.hasAttackSource() + && meta.hasTargetEntity() + && meta.getTargetEntityOrNull() instanceof LivingEntity); } @Override @@ -47,23 +57,23 @@ public class Ambers extends SkillHandler implements Listener @EventHandler public void spawnAmber(PlayerAttackEvent event) { MMOPlayerData data = event.getAttacker().getData(); - if (!event.getAttack().getDamage().hasType(DamageType.SKILL)) - return; + if (!event.getAttack().getDamage().hasType(DamageType.SKILL)) return; PassiveSkill passive = data.getPassiveSkillMap().getSkill(this); - if (passive == null) - return; + if (passive == null) return; - passive.getTriggeredSkill().cast(new TriggerMetadata(event)); + passive.getTriggeredSkill().cast(new TriggerMetadata(event, TriggerType.API)); } - public static class Amber extends BukkitRunnable { + class Amber extends BukkitRunnable { private final Location loc; private final MMOPlayerData data; private final double percent; private int j; + private static final double RADIUS_SQUARED = 3; + private Amber(MMOPlayerData data, Location source, Location loc, double percent) { this.loc = loc; this.data = data; @@ -80,10 +90,9 @@ public class Ambers extends SkillHandler implements Listener return; } - if (data.getPlayer().getLocation().distanceSquared(loc) < 2) { + if (data.getPlayer().getLocation().add(0, 1, 0).distanceSquared(loc) < RADIUS_SQUARED) { data.getPlayer().playSound(data.getPlayer().getLocation(), Sound.BLOCK_END_PORTAL_FRAME_FILL, 1, 1); - // data.getSkillData().ambers++; // Give mana back PlayerData playerData = PlayerData.get(data); @@ -95,7 +104,11 @@ public class Ambers extends SkillHandler implements Listener } for (int j = 0; j < 5; j++) - loc.getWorld().spawnParticle(VParticle.ENTITY_EFFECT.get(), loc, 0, 1, 0.647, 0, 1); + if (legacyParticles) + loc.getWorld().spawnParticle(VParticle.ENTITY_EFFECT.get(), loc, 0, 1, 0.647, 0, 1); + else + loc.getWorld().spawnParticle(VParticle.ENTITY_EFFECT.get(), loc, 0, 1, 0.647, 0, 1, Color.ORANGE); + loc.getWorld().spawnParticle(VParticle.REDSTONE.get(), loc, 1, new Particle.DustOptions(Color.ORANGE, 1.3f)); } } From bfc91619a9cfb8da646360085b6623c4af52e35a Mon Sep 17 00:00:00 2001 From: Jules Date: Tue, 22 Oct 2024 15:11:17 +0200 Subject: [PATCH 3/6] Fixed %mmocore_cast_slot_offset_%. New option for skill bar casting mode to not use lowest keybinds --- .../mmocore/api/player/PlayerData.java | 3 +- .../command/MMOCoreCommandTreeRoot.java | 2 + .../comp/placeholder/RPGPlaceholders.java | 15 ++--- .../mmocore/skill/binding/BoundSkillInfo.java | 10 ++++ .../skill/cast/SkillCastingHandler.java | 4 ++ .../mmocore/skill/cast/SkillCastingMode.java | 11 +++- .../mmocore/skill/cast/handler/SkillBar.java | 56 ++++++++++++------- .../mmocore/skill/list/Neptune_Gift.java | 4 +- .../mmocore/skill/list/Sneaky_Picky.java | 6 +- MMOCore-Dist/src/main/resources/config.yml | 1 + 10 files changed, 76 insertions(+), 36 deletions(-) diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/player/PlayerData.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/player/PlayerData.java index 4a6cda98..383e4970 100644 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/player/PlayerData.java +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/player/PlayerData.java @@ -1136,7 +1136,7 @@ public class PlayerData extends SynchronizedDataHolder implements OfflinePlayerD Bukkit.getPluginManager().callEvent(event); if (event.isCancelled()) return false; - this.skillCasting = SkillCastingMode.getCurrent().newInstance(this); + this.skillCasting = SkillCastingMode.getInstance().newInstance(this); return true; } @@ -1321,6 +1321,7 @@ public class PlayerData extends SynchronizedDataHolder implements OfflinePlayerD unbindSkill(slot); final SkillSlot skillSlot = getProfess().getSkillSlot(slot); boundSkills.put(slot, new BoundSkillInfo(skillSlot, skill, this)); + SkillCastingMode.getInstance().onSkillBound(this); } @Nullable diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/command/MMOCoreCommandTreeRoot.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/command/MMOCoreCommandTreeRoot.java index dcefd387..de02f0cb 100644 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/command/MMOCoreCommandTreeRoot.java +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/command/MMOCoreCommandTreeRoot.java @@ -3,6 +3,7 @@ package net.Indyuce.mmocore.command; import io.lumine.mythic.lib.command.api.CommandTreeRoot; import io.lumine.mythic.lib.command.api.Parameter; import net.Indyuce.mmocore.MMOCore; +import net.Indyuce.mmocore.command.rpg.CastCommandTreeNode; import net.Indyuce.mmocore.command.rpg.CoinsCommandTreeNode; import net.Indyuce.mmocore.command.rpg.NoteCommandTreeNode; import net.Indyuce.mmocore.command.rpg.ReloadCommandTreeNode; @@ -26,6 +27,7 @@ public class MMOCoreCommandTreeRoot extends CommandTreeRoot implements CommandEx super("mmocore", "mmocore.admin"); addChild(new ReloadCommandTreeNode(this)); + addChild(new CastCommandTreeNode(this)); addChild(new CoinsCommandTreeNode(this)); addChild(new NoteCommandTreeNode(this)); addChild(new AdminCommandTreeNode(this)); diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/comp/placeholder/RPGPlaceholders.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/comp/placeholder/RPGPlaceholders.java index 4f4417dc..addbbcf4 100644 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/comp/placeholder/RPGPlaceholders.java +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/comp/placeholder/RPGPlaceholders.java @@ -162,20 +162,15 @@ public class RPGPlaceholders extends PlaceholderExpansion { else if (identifier.startsWith("cast_slot_offset_")) { final Player online = player.getPlayer(); Validate.notNull(online, "Player is offline"); - final AtomicInteger query = new AtomicInteger(Integer.parseInt(identifier.substring(17))); + final int query = Integer.parseInt(identifier.substring(17)); - BoundSkillInfo bound = playerData.getBoundSkills().get(query.get()); + BoundSkillInfo bound = playerData.getBoundSkills().get(query); if (bound == null || bound.isPassive()) return String.valueOf(0); - // Offset due to passive skills - playerData.getBoundSkills().forEach((slot, skill) -> { - if (skill.isPassive() && slot < query.get()) - query.addAndGet(-1); - }); - + int slot = bound.skillBarCastSlot; // Offset due to player's hotbar location - if (online.getInventory().getHeldItemSlot() < query.get()) query.addAndGet(1); - return String.valueOf(query.get()); + if (online.getInventory().getHeldItemSlot() < slot) slot++; + return String.valueOf(slot); } // Is there a passive skill bound to given slot diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/binding/BoundSkillInfo.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/binding/BoundSkillInfo.java index ac15d614..4a126d84 100644 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/binding/BoundSkillInfo.java +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/binding/BoundSkillInfo.java @@ -14,6 +14,16 @@ public class BoundSkillInfo implements Closeable { private final PlayerData playerData; private final ClassSkill classSkill; + /** + * If the skill casting mode is set to skill bar, then + * this corresponds to the slot the player needs to click + * (not taking into account casting slot offset) in order + * to cast this skill. + *

+ * If it is a passive skill, this value has no meaning. + */ + public int skillBarCastSlot; + /** * Non-permanent passive skills must be registered inside * MythicLib when bound. When set to null, the skill is either diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/cast/SkillCastingHandler.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/cast/SkillCastingHandler.java index b16d999b..22760781 100644 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/cast/SkillCastingHandler.java +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/cast/SkillCastingHandler.java @@ -29,4 +29,8 @@ public abstract class SkillCastingHandler implements Listener { @NotNull public abstract SkillCastingInstance newInstance(@NotNull PlayerData player); + + public void onSkillBound(@NotNull PlayerData player) { + // Nothing by default + } } diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/cast/SkillCastingMode.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/cast/SkillCastingMode.java index f029f35c..f2368038 100644 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/cast/SkillCastingMode.java +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/cast/SkillCastingMode.java @@ -78,7 +78,16 @@ public enum SkillCastingMode { } @NotNull - public static SkillCastingHandler getCurrent() { + public static SkillCastingHandler getInstance() { return Objects.requireNonNull(current, "Skill casting mode hasn't been initialized yet"); } + + /** + * @see #getInstance() + * @deprecated + */ + @Deprecated + public static SkillCastingHandler getCurrent() { + return getInstance(); + } } diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/cast/handler/SkillBar.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/cast/handler/SkillBar.java index 7195076e..a5be87ed 100644 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/cast/handler/SkillBar.java +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/cast/handler/SkillBar.java @@ -1,9 +1,6 @@ package net.Indyuce.mmocore.skill.cast.handler; import io.lumine.mythic.lib.UtilityMethods; -import io.lumine.mythic.lib.api.player.EquipmentSlot; -import io.lumine.mythic.lib.player.PlayerMetadata; -import io.lumine.mythic.lib.skill.trigger.TriggerMetadata; import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.api.ConfigMessage; import net.Indyuce.mmocore.api.SoundEvent; @@ -21,18 +18,20 @@ import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.player.PlayerItemHeldEvent; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.Objects; public class SkillBar extends SkillCastingHandler { private final PlayerKey mainKey; - private final boolean disableSneak; + private final boolean disableSneak, lowestKeybinds; public SkillBar(@NotNull ConfigurationSection config) { super(config); mainKey = PlayerKey.valueOf(UtilityMethods.enumName(Objects.requireNonNull(config.getString("open"), "Could not find open key"))); disableSneak = config.getBoolean("disable-sneak"); + lowestKeybinds = config.getBoolean("use-lowest-keybinds"); } @Override @@ -45,6 +44,23 @@ public class SkillBar extends SkillCastingHandler { return SkillCastingMode.SKILL_BAR; } + @Override + public void onSkillBound(@NotNull PlayerData player) { + + // Lowest indices = start at slot 1 and increase + if (lowestKeybinds) { + + int slot = 1; + + for (BoundSkillInfo bound : player.getBoundSkills().values()) + // Set cast slot and increment slot + if (!bound.isPassive()) bound.skillBarCastSlot = slot++; + } + + // Otherwise, direct correspondance + else player.getBoundSkills().forEach((slot, bound) -> bound.skillBarCastSlot = slot); + } + @EventHandler public void enterSkillCasting(PlayerKeyPressEvent event) { if (event.getPressed() != mainKey) return; @@ -80,7 +96,7 @@ public class SkillBar extends SkillCastingHandler { } @EventHandler - public void onSkillCast(PlayerItemHeldEvent event) { + public void onItemHeld(PlayerItemHeldEvent event) { if (!event.getPlayer().equals(getCaster().getPlayer())) return; // Extra option to improve support with other plugins @@ -96,18 +112,18 @@ public class SkillBar extends SkillCastingHandler { event.setCancelled(true); refreshTimeOut(); - final int activeSlot = event.getNewSlot() + (event.getNewSlot() >= player.getInventory().getHeldItemSlot() ? -1 : 0); - /* - * The event is called again soon after the first since when - * cancelling the first one, the player held item slot must go back - * to the previous one. - */ - if (activeSlot < getActiveSkills().size()) { - final ClassSkill classSkill = getActiveSkills().get(activeSlot).getClassSkill(); - final PlayerMetadata caster = getCaster().getMMOPlayerData().getStatMap().cache(EquipmentSlot.MAIN_HAND); - classSkill.toCastable(getCaster()).cast(new TriggerMetadata(caster, null, null)); - } + // Look for skill with given slot + ClassSkill classSkill = findSkillToCast(player.getInventory().getHeldItemSlot(), event.getNewSlot()); + if (classSkill != null) classSkill.toCastable(getCaster()).cast(getCaster().getMMOPlayerData()); + } + + @Nullable + private ClassSkill findSkillToCast(int currentSlot, int clickedSlot) { + for (BoundSkillInfo info : this.getActiveSkills()) + if (info.skillBarCastSlot + (currentSlot < info.skillBarCastSlot ? 1 : 0) == 1 + clickedSlot) + return info.getClassSkill(); + return null; } @EventHandler @@ -128,12 +144,12 @@ public class SkillBar extends SkillCastingHandler { @NotNull private String getFormat(PlayerData data) { - final StringBuilder str = new StringBuilder(); - if (!data.isOnline()) return str.toString(); + if (!data.isOnline()) return ""; - int slot = 1; + final StringBuilder str = new StringBuilder(); for (BoundSkillInfo active : getActiveSkills()) { final ClassSkill skill = active.getClassSkill(); + final int slot = active.skillBarCastSlot; str.append(str.isEmpty() ? "" : split).append( (onCooldown(data, skill) ? onCooldown.replace("{cooldown}", @@ -141,8 +157,8 @@ public class SkillBar extends SkillCastingHandler { noMana(data, skill) ? noMana : (noStamina(data, skill) ? noStamina : ready)) .replace("{index}", String.valueOf(slot + (data.getPlayer().getInventory().getHeldItemSlot() < slot ? 1 : 0))) .replace("{skill}", skill.getSkill().getName())); - slot++; } + return MMOCore.plugin.placeholderParser.parse(data.getPlayer(), str.toString()); } diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/list/Neptune_Gift.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/list/Neptune_Gift.java index 5fe28639..555c071a 100644 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/list/Neptune_Gift.java +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/list/Neptune_Gift.java @@ -4,12 +4,11 @@ import io.lumine.mythic.lib.player.skill.PassiveSkill; import io.lumine.mythic.lib.skill.SkillMetadata; import io.lumine.mythic.lib.skill.handler.SkillHandler; import io.lumine.mythic.lib.skill.result.def.SimpleSkillResult; -import io.lumine.mythic.lib.skill.trigger.TriggerMetadata; -import io.lumine.mythic.lib.skill.trigger.TriggerType; import net.Indyuce.mmocore.api.event.PlayerResourceUpdateEvent; import org.bukkit.Material; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; +import org.jetbrains.annotations.NotNull; public class Neptune_Gift extends SkillHandler implements Listener { public Neptune_Gift() { @@ -18,6 +17,7 @@ public class Neptune_Gift extends SkillHandler implements Lis registerModifiers("extra"); } + @NotNull @Override public SimpleSkillResult getResult(SkillMetadata meta) { throw new RuntimeException("Not supported"); diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/list/Sneaky_Picky.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/list/Sneaky_Picky.java index 8e303156..b32611de 100644 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/list/Sneaky_Picky.java +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/list/Sneaky_Picky.java @@ -14,6 +14,7 @@ import org.bukkit.Sound; import org.bukkit.entity.LivingEntity; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; +import org.jetbrains.annotations.NotNull; public class Sneaky_Picky extends SkillHandler implements Listener { public Sneaky_Picky() { @@ -22,15 +23,16 @@ public class Sneaky_Picky extends SkillHandler implements Lis registerModifiers("extra"); } + @NotNull @Override public SimpleSkillResult getResult(SkillMetadata meta) { - return new SimpleSkillResult(meta.hasAttackBound() && meta.hasTargetEntity() && meta.getTargetEntityOrNull() instanceof LivingEntity); + return new SimpleSkillResult(meta.hasAttackSource() && meta.hasTargetEntity() && meta.getTargetEntityOrNull() instanceof LivingEntity); } @Override public void whenCast(SimpleSkillResult result, SkillMetadata skillMeta) { LivingEntity target = (LivingEntity) skillMeta.getTargetEntity(); - skillMeta.getAttack().getDamage().multiplicativeModifier(1 + skillMeta.getParameter("extra") / 100, DamageType.WEAPON); + skillMeta.getAttackSource().getDamage().multiplicativeModifier(1 + skillMeta.getParameter("extra") / 100, DamageType.WEAPON); target.getWorld().spawnParticle(VParticle.SMOKE.get(), 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/MMOCore-Dist/src/main/resources/config.yml b/MMOCore-Dist/src/main/resources/config.yml index 8dad0204..9d0104a6 100644 --- a/MMOCore-Dist/src/main/resources/config.yml +++ b/MMOCore-Dist/src/main/resources/config.yml @@ -106,6 +106,7 @@ skill-casting: mode: SKILL_BAR open: SWAP_HANDS disable-sneak: false + use-lowest-keybinds: true loot-chests: From 177ea5014ecdc159e6a2d8d2ed0f97f8ba40e0d8 Mon Sep 17 00:00:00 2001 From: Jules Date: Tue, 22 Oct 2024 15:28:21 +0200 Subject: [PATCH 4/6] Added /mmocore cast first/specific --- .../command/rpg/CastCommandTreeNode.java | 21 +++++++ .../rpg/cast/FirstCommandTreeNode.java | 61 +++++++++++++++++++ .../rpg/cast/SpecificCommandTreeNode.java | 59 ++++++++++++++++++ 3 files changed, 141 insertions(+) create mode 100644 MMOCore-API/src/main/java/net/Indyuce/mmocore/command/rpg/CastCommandTreeNode.java create mode 100644 MMOCore-API/src/main/java/net/Indyuce/mmocore/command/rpg/cast/FirstCommandTreeNode.java create mode 100644 MMOCore-API/src/main/java/net/Indyuce/mmocore/command/rpg/cast/SpecificCommandTreeNode.java diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/command/rpg/CastCommandTreeNode.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/command/rpg/CastCommandTreeNode.java new file mode 100644 index 00000000..1a60a3ef --- /dev/null +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/command/rpg/CastCommandTreeNode.java @@ -0,0 +1,21 @@ +package net.Indyuce.mmocore.command.rpg; + +import io.lumine.mythic.lib.command.api.CommandTreeNode; +import net.Indyuce.mmocore.command.rpg.cast.FirstCommandTreeNode; +import net.Indyuce.mmocore.command.rpg.cast.SpecificCommandTreeNode; +import org.bukkit.command.CommandSender; +import org.jetbrains.annotations.NotNull; + +public class CastCommandTreeNode extends CommandTreeNode { + public CastCommandTreeNode(CommandTreeNode parent) { + super(parent, "cast"); + + addChild(new FirstCommandTreeNode(this)); + addChild(new SpecificCommandTreeNode(this)); + } + + @Override + public @NotNull CommandResult execute(CommandSender commandSender, String[] strings) { + return CommandResult.THROW_USAGE; + } +} diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/command/rpg/cast/FirstCommandTreeNode.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/command/rpg/cast/FirstCommandTreeNode.java new file mode 100644 index 00000000..41fa69b7 --- /dev/null +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/command/rpg/cast/FirstCommandTreeNode.java @@ -0,0 +1,61 @@ +package net.Indyuce.mmocore.command.rpg.cast; + +import io.lumine.mythic.lib.command.api.CommandTreeNode; +import io.lumine.mythic.lib.command.api.Parameter; +import net.Indyuce.mmocore.api.player.PlayerData; +import net.Indyuce.mmocore.skill.ClassSkill; +import org.apache.commons.lang.Validate; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +public class FirstCommandTreeNode extends CommandTreeNode { + public FirstCommandTreeNode(CommandTreeNode parent) { + super(parent, "first"); + + addParameter(Parameter.PLAYER); + addParameter(SpecificCommandTreeNode.INTEGER); + } + + @Override + public CommandResult execute(CommandSender sender, String[] args) { + if (args.length < 3) return CommandResult.THROW_USAGE; + + Player player = Bukkit.getPlayer(args[2]); + if (player == null) { + sender.sendMessage(ChatColor.RED + "Could not find the player called " + args[2] + "."); + return CommandResult.FAILURE; + } + PlayerData data = PlayerData.get(player); + + int slot; + try { + slot = Integer.parseInt(args[3]); + Validate.isTrue(slot > 0); + } catch (Exception exception) { + sender.sendMessage(ChatColor.RED + args[3] + " is not a valid integer."); + return CommandResult.FAILURE; + } + + List slots = data.getBoundSkills().entrySet().stream() + .filter(e -> !e.getValue().isPassive()) + .map(Map.Entry::getKey) + .sorted(Integer::compare).collect(Collectors.toList()); + if (slot > slots.size()) { + sender.sendMessage(ChatColor.RED + "Player " + player.getName() + " only has active skills on slots " + slots + "."); + return CommandResult.FAILURE; + } + + ClassSkill skill = data.getBoundSkill(slots.get(slot - 1)); + Validate.notNull(skill, "Internal error: skill is null"); + Validate.isTrue(!skill.getSkill().getTrigger().isPassive(), "Internal error: skill is passive"); + + boolean success = skill.toCastable(data).cast(data.getMMOPlayerData()).isSuccessful(); + return success ? CommandResult.SUCCESS : CommandResult.FAILURE; + } +} diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/command/rpg/cast/SpecificCommandTreeNode.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/command/rpg/cast/SpecificCommandTreeNode.java new file mode 100644 index 00000000..560d3777 --- /dev/null +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/command/rpg/cast/SpecificCommandTreeNode.java @@ -0,0 +1,59 @@ +package net.Indyuce.mmocore.command.rpg.cast; + +import io.lumine.mythic.lib.command.api.CommandTreeNode; +import io.lumine.mythic.lib.command.api.Parameter; +import net.Indyuce.mmocore.api.player.PlayerData; +import net.Indyuce.mmocore.skill.ClassSkill; +import org.apache.commons.lang.Validate; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.util.Arrays; + +public class SpecificCommandTreeNode extends CommandTreeNode { + public static final Parameter INTEGER = new Parameter("slot", false, (explorer, list) -> list.addAll(Arrays.asList("1", "2", "3", "4", "5", "6"))); + + public SpecificCommandTreeNode(CommandTreeNode parent) { + super(parent, "specific"); + + addParameter(Parameter.PLAYER); + addParameter(INTEGER); + } + + @Override + public CommandResult execute(CommandSender sender, String[] args) { + if (args.length < 3) return CommandResult.THROW_USAGE; + + Player player = Bukkit.getPlayer(args[2]); + if (player == null) { + sender.sendMessage(ChatColor.RED + "Could not find the player called " + args[2] + "."); + return CommandResult.FAILURE; + } + PlayerData data = PlayerData.get(player); + + int slot; + try { + slot = Integer.parseInt(args[3]); + Validate.isTrue(slot > 0); + } catch (Exception exception) { + sender.sendMessage(ChatColor.RED + args[3] + " is not a valid integer."); + return CommandResult.FAILURE; + } + + ClassSkill skill = data.getBoundSkill(slot); + if (skill == null) { + sender.sendMessage(ChatColor.RED + "Found no skill bound to slot " + slot + " of player " + player.getName() + "."); + return CommandResult.FAILURE; + } + + if (skill.getSkill().getTrigger().isPassive()) { + sender.sendMessage(ChatColor.RED + "Skill '" + skill.getSkill().getName() + "' bound to slot " + slot + " is passive."); + return CommandResult.FAILURE; + } + + boolean success = skill.toCastable(data).cast(data.getMMOPlayerData()).isSuccessful(); + return success ? CommandResult.SUCCESS : CommandResult.FAILURE; + } +} From be373b65f8c7c39d350e6314fe6a089311b8bbc5 Mon Sep 17 00:00:00 2001 From: Jules Date: Thu, 24 Oct 2024 17:27:47 +0200 Subject: [PATCH 5/6] Changed method signature for PlayerExpGainEvent#setExperience(int) --- .../api/event/PlayerExperienceGainEvent.java | 100 +++++++++--------- 1 file changed, 52 insertions(+), 48 deletions(-) diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/event/PlayerExperienceGainEvent.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/event/PlayerExperienceGainEvent.java index 046c6e65..e6515d97 100644 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/event/PlayerExperienceGainEvent.java +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/event/PlayerExperienceGainEvent.java @@ -1,72 +1,76 @@ package net.Indyuce.mmocore.api.event; -import javax.annotation.Nullable; - import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.experience.EXPSource; +import net.Indyuce.mmocore.experience.Profession; import org.bukkit.event.Cancellable; import org.bukkit.event.HandlerList; -import net.Indyuce.mmocore.experience.Profession; +import javax.annotation.Nullable; public class PlayerExperienceGainEvent extends PlayerDataEvent implements Cancellable { - private static final HandlerList handlers = new HandlerList(); + private static final HandlerList handlers = new HandlerList(); - // if null, this is main experience - private final Profession profession; - private final EXPSource source; + // if null, this is main experience + private final Profession profession; + private final EXPSource source; - private double experience; - private boolean cancelled; + private double experience; + private boolean cancelled; - public PlayerExperienceGainEvent(PlayerData player, double experience, EXPSource source) { - this(player, null, experience, source); - } + public PlayerExperienceGainEvent(PlayerData player, double experience, EXPSource source) { + this(player, null, experience, source); + } - public PlayerExperienceGainEvent(PlayerData player, @Nullable Profession profession, double experience, EXPSource source) { - super(player); + public PlayerExperienceGainEvent(PlayerData player, @Nullable Profession profession, double experience, EXPSource source) { + super(player); - this.profession = profession; - this.experience = experience; - this.source = source; - } + this.profession = profession; + this.experience = experience; + this.source = source; + } - public double getExperience() { - return experience; - } + public double getExperience() { + return experience; + } - public void setExperience(int experience) { - this.experience = experience; - } + @Deprecated + public void setExperience(int experience) { + setExperience((double) experience); + } - @Override - public boolean isCancelled() { - return cancelled; - } + public void setExperience(double experience) { + this.experience = experience; + } - @Override - public void setCancelled(boolean cancelled) { - this.cancelled = cancelled; - } + @Override + public boolean isCancelled() { + return cancelled; + } - public boolean hasProfession() { - return profession != null; - } + @Override + public void setCancelled(boolean cancelled) { + this.cancelled = cancelled; + } - public Profession getProfession() { - return profession; - } + public boolean hasProfession() { + return profession != null; + } - public EXPSource getSource() { - return source; - } + public Profession getProfession() { + return profession; + } - @Override - public HandlerList getHandlers() { - return handlers; - } + public EXPSource getSource() { + return source; + } - public static HandlerList getHandlerList() { - return handlers; - } + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } } From 1d3ff132d578df8666d85c02abc568bc9e232901 Mon Sep 17 00:00:00 2001 From: Jules Date: Thu, 24 Oct 2024 17:28:25 +0200 Subject: [PATCH 6/6] Updated version number --- MMOCore-API/pom.xml | 2 +- MMOCore-Dist/pom.xml | 4 ++-- pom.xml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/MMOCore-API/pom.xml b/MMOCore-API/pom.xml index 90b17b9d..fce3cf86 100644 --- a/MMOCore-API/pom.xml +++ b/MMOCore-API/pom.xml @@ -5,7 +5,7 @@ MMOCore net.Indyuce - 1.12.1-SNAPSHOT + 1.13.1-SNAPSHOT 4.0.0 diff --git a/MMOCore-Dist/pom.xml b/MMOCore-Dist/pom.xml index 369687f6..5a501ecb 100644 --- a/MMOCore-Dist/pom.xml +++ b/MMOCore-Dist/pom.xml @@ -5,7 +5,7 @@ MMOCore net.Indyuce - 1.12.1-SNAPSHOT + 1.13.1-SNAPSHOT 4.0.0 @@ -67,7 +67,7 @@ net.Indyuce MMOCore-API - 1.12.1-SNAPSHOT + 1.13.1-SNAPSHOT true diff --git a/pom.xml b/pom.xml index a940f48c..26c336a8 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ net.Indyuce MMOCore pom - 1.12.1-SNAPSHOT + 1.13.1-SNAPSHOT MMOCore-API