diff --git a/.gradle/8.8/checksums/checksums.lock b/.gradle/8.8/checksums/checksums.lock index 17750ef..166c142 100644 Binary files a/.gradle/8.8/checksums/checksums.lock and b/.gradle/8.8/checksums/checksums.lock differ diff --git a/.gradle/8.8/executionHistory/executionHistory.bin b/.gradle/8.8/executionHistory/executionHistory.bin index 2941621..71e7a1e 100644 Binary files a/.gradle/8.8/executionHistory/executionHistory.bin and b/.gradle/8.8/executionHistory/executionHistory.bin differ diff --git a/.gradle/8.8/executionHistory/executionHistory.lock b/.gradle/8.8/executionHistory/executionHistory.lock index 28251b7..6d10104 100644 Binary files a/.gradle/8.8/executionHistory/executionHistory.lock and b/.gradle/8.8/executionHistory/executionHistory.lock differ diff --git a/.gradle/8.8/fileHashes/fileHashes.bin b/.gradle/8.8/fileHashes/fileHashes.bin index 96a88a3..e399e01 100644 Binary files a/.gradle/8.8/fileHashes/fileHashes.bin and b/.gradle/8.8/fileHashes/fileHashes.bin differ diff --git a/.gradle/8.8/fileHashes/fileHashes.lock b/.gradle/8.8/fileHashes/fileHashes.lock index 97e7d73..5966817 100644 Binary files a/.gradle/8.8/fileHashes/fileHashes.lock and b/.gradle/8.8/fileHashes/fileHashes.lock differ diff --git a/.gradle/8.8/fileHashes/resourceHashesCache.bin b/.gradle/8.8/fileHashes/resourceHashesCache.bin index d0e1e8d..eaf164d 100644 Binary files a/.gradle/8.8/fileHashes/resourceHashesCache.bin and b/.gradle/8.8/fileHashes/resourceHashesCache.bin differ diff --git a/.gradle/buildOutputCleanup/buildOutputCleanup.lock b/.gradle/buildOutputCleanup/buildOutputCleanup.lock index a157a71..e19ffa1 100644 Binary files a/.gradle/buildOutputCleanup/buildOutputCleanup.lock and b/.gradle/buildOutputCleanup/buildOutputCleanup.lock differ diff --git a/build/resources/main/plugin.yml b/build/resources/main/plugin.yml index 4625655..cf54608 100644 --- a/build/resources/main/plugin.yml +++ b/build/resources/main/plugin.yml @@ -18,4 +18,8 @@ commands: usage: "/asmp usage" aliases: - asmp - - armor_smp \ No newline at end of file + - armor_smp + ability: + description: Utilize unique abilities. + aliases: + - a \ No newline at end of file diff --git a/build/tmp/compileJava/previous-compilation-data.bin b/build/tmp/compileJava/previous-compilation-data.bin index 7c424f8..47d25ae 100644 Binary files a/build/tmp/compileJava/previous-compilation-data.bin and b/build/tmp/compileJava/previous-compilation-data.bin differ diff --git a/src/main/java/me/trouper/armorsmp/ArmorSMP.java b/src/main/java/me/trouper/armorsmp/ArmorSMP.java index c41bbc3..b54cd90 100644 --- a/src/main/java/me/trouper/armorsmp/ArmorSMP.java +++ b/src/main/java/me/trouper/armorsmp/ArmorSMP.java @@ -1,6 +1,7 @@ package me.trouper.armorsmp; import io.github.itzispyder.pdk.PDK; +import io.github.itzispyder.pdk.utils.misc.Timer; import me.trouper.armorsmp.server.Manager; import org.bukkit.plugin.java.JavaPlugin; @@ -8,9 +9,11 @@ public final class ArmorSMP extends JavaPlugin { private static ArmorSMP instance; private Manager manager; + private Timer timer; @Override public void onLoad() { + timer = Timer.start(); getLogger().info("Instantiating Plugin"); instance = this; @@ -25,6 +28,7 @@ public final class ArmorSMP extends JavaPlugin { getLogger().info("Initializing Manager"); manager.init(); + getLogger().info("Successfully enabled ArmorSMP in %s".formatted(timer.end().getStampPrecise())); } @Override diff --git a/src/main/java/me/trouper/armorsmp/data/Unique.java b/src/main/java/me/trouper/armorsmp/data/Unique.java index 9313e65..9dabafa 100644 --- a/src/main/java/me/trouper/armorsmp/data/Unique.java +++ b/src/main/java/me/trouper/armorsmp/data/Unique.java @@ -1,15 +1,26 @@ package me.trouper.armorsmp.data; import io.github.itzispyder.pdk.plugin.builders.ItemBuilder; +import io.github.itzispyder.pdk.utils.raytracers.CustomDisplayRaytracer; +import me.trouper.armorsmp.ArmorSMP; import me.trouper.armorsmp.utils.Text; +import org.bukkit.Location; import org.bukkit.Material; +import org.bukkit.Particle; +import org.bukkit.World; +import org.bukkit.block.Block; import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.AreaEffectCloud; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; +import org.bukkit.util.Vector; import java.util.function.Consumer; +import java.util.stream.Stream; public enum Unique { HELMET(ItemBuilder.create() @@ -46,6 +57,25 @@ public enum Unique { p.addPotionEffect(new PotionEffect(PotionEffectType.STRENGTH,21,0,true,false,false)); p.addPotionEffect(new PotionEffect(PotionEffectType.RESISTANCE,21,0,true,false,false)); }, (p) -> { + // TODO: Test Dragon's Breath + World world = p.getWorld(); + + Location eyeLocation = p.getEyeLocation(); + Vector direction = eyeLocation.getDirection(); + + Location hit = CustomDisplayRaytracer.trace(eyeLocation,direction,30,point -> { + Location particleLocation = point.getLoc(); + world.spawnParticle(Particle.DRAGON_BREATH, particleLocation, 10, 0.2, 0.2, 0.2, 0.01); + return !point.getBlock().isPassable(); + }).getLoc(); + + AreaEffectCloud cloud = (AreaEffectCloud) world.spawnEntity(hit, EntityType.AREA_EFFECT_CLOUD); + cloud.setRadius(3.0f); + cloud.setDuration(200); + cloud.setParticle(Particle.DRAGON_BREATH); + cloud.addCustomEffect(PotionEffectType.INSTANT_DAMAGE.createEffect(1,1),true); + cloud.setOwnerUniqueId(p.getUniqueId()); + }, 50), LEGGINGS(ItemBuilder.create() .material(Material.NETHERITE_LEGGINGS) @@ -61,9 +91,23 @@ public enum Unique { .build(), "Netherite Leggings", (p) -> { p.addPotionEffect(new PotionEffect(PotionEffectType.RESISTANCE,21,0,true,false,false)); - }, (p) -> { - // TODO: yoink shield ability from OgreDupeAlias + // TODO: Test Shield + Stream toKnockBack = p.getNearbyEntities(10,10,10).stream().filter(target -> { + if (!(target instanceof Player v)) return false; + boolean tooClose = target.getLocation().distance(p.getLocation()) < 10; + boolean self = target.getUniqueId().equals(p.getUniqueId()); + boolean trusted = ArmorSMP.getInstance().getManager().trust.getTrustees(p).contains(v.getUniqueId().toString()); + return tooClose && !self && !trusted; + }); + toKnockBack.forEach((target -> { + Vector direction = target.getLocation().toVector().subtract(p.getLocation().toVector()); + direction.normalize(); + direction.multiply(2); + direction.setY(direction.getY() + 0.5); + + target.setVelocity(direction); + })); }, 45), BOOTS(ItemBuilder.create() .material(Material.NETHERITE_BOOTS) @@ -82,7 +126,10 @@ public enum Unique { "Netherite Boots", (p) -> { p.addPotionEffect(new PotionEffect(PotionEffectType.SPEED,21,0,true,false,false)); }, (p) -> { - // TODO: Vector math for dash ability + Vector direction = p.getLocation().getDirection(); + Vector velocity = direction.multiply(4); // TODO: Test Vector + + p.setVelocity(velocity); }, 50), MACE(ItemBuilder.create() .material(Material.MACE) diff --git a/src/main/java/me/trouper/armorsmp/server/commands/AbilityCommand.java b/src/main/java/me/trouper/armorsmp/server/commands/AbilityCommand.java index e5d0383..fccccdc 100644 --- a/src/main/java/me/trouper/armorsmp/server/commands/AbilityCommand.java +++ b/src/main/java/me/trouper/armorsmp/server/commands/AbilityCommand.java @@ -6,6 +6,7 @@ import io.github.itzispyder.pdk.commands.CustomCommand; import io.github.itzispyder.pdk.commands.completions.CompletionBuilder; import io.github.itzispyder.pdk.utils.misc.Cooldown; import io.github.itzispyder.pdk.utils.misc.Pair; +import me.trouper.armorsmp.ArmorSMP; import me.trouper.armorsmp.data.Unique; import me.trouper.armorsmp.utils.Text; import org.bukkit.command.Command; @@ -13,12 +14,13 @@ import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import java.util.Arrays; +import java.util.Objects; import java.util.UUID; @CommandRegistry(value = "ability", printStackTrace = true, playersOnly = true) public class AbilityCommand implements CustomCommand { - Cooldown> abilityCooldown = new Cooldown<>(); + private final Cooldown> abilityCooldown = new Cooldown<>(); @Override public void dispatchCommand(CommandSender sender, Command command, String label, Args args) { @@ -28,6 +30,10 @@ public class AbilityCommand implements CustomCommand { Text.sendMessage(false, Text.Pallet.ERROR, sender, "Error: {0} is not a valid unique. Please choose from these values: ", args.get(2).toString(), Arrays.toString(Unique.values())); return; } + if (p.getUniqueId().toString().equals(ArmorSMP.getInstance().getManager().io.storage.uniques.owners.get(piece))) { + Text.sendMessage(false, Text.Pallet.WARNING, sender, "You do not own {0}.",piece.getCanonical()); + return; + } if (abilityCooldown.isOnCooldown(Pair.of(piece,p.getUniqueId()))) { Text.sendMessage(false, Text.Pallet.WARNING, sender, "The ability for your {0} is on cooldown for {1} seconds.",piece.getCanonical(),abilityCooldown.getCooldownSec(Pair.of(piece,p.getUniqueId()))); return; diff --git a/src/main/java/me/trouper/armorsmp/server/events/ItemDestroyEvents.java b/src/main/java/me/trouper/armorsmp/server/events/ItemDestroyEvents.java index 28310c2..2ff9952 100644 --- a/src/main/java/me/trouper/armorsmp/server/events/ItemDestroyEvents.java +++ b/src/main/java/me/trouper/armorsmp/server/events/ItemDestroyEvents.java @@ -5,9 +5,7 @@ import io.papermc.paper.event.entity.EntityDamageItemEvent; import me.trouper.armorsmp.data.Unique; import org.bukkit.entity.Item; import org.bukkit.event.EventHandler; -import org.bukkit.event.entity.EntityDamageByBlockEvent; -import org.bukkit.event.entity.EntityDamageByEntityEvent; -import org.bukkit.event.entity.ItemDespawnEvent; +import org.bukkit.event.entity.*; import org.bukkit.inventory.ItemStack; public class ItemDestroyEvents implements CustomListener { @@ -28,7 +26,31 @@ public class ItemDestroyEvents implements CustomListener { } @EventHandler - public void onBlockDamage(EntityDamageByEntityEvent e) { + public void onEntityDamage(EntityDamageByEntityEvent e) { + if (!(e.getEntity() instanceof Item i)) return; + if (!Unique.isUnique(i.getItemStack())) return; + + e.setCancelled(true); + } + + @EventHandler + public void onCombust(EntityCombustEvent e) { + if (!(e.getEntity() instanceof Item i)) return; + if (!Unique.isUnique(i.getItemStack())) return; + + e.setCancelled(true); + } + + @EventHandler + public void onEntityCombust(EntityCombustByEntityEvent e) { + if (!(e.getEntity() instanceof Item i)) return; + if (!Unique.isUnique(i.getItemStack())) return; + + e.setCancelled(true); + } + + @EventHandler + public void onBlockCombust(EntityCombustByBlockEvent e) { if (!(e.getEntity() instanceof Item i)) return; if (!Unique.isUnique(i.getItemStack())) return; diff --git a/src/main/java/me/trouper/armorsmp/server/events/JoinEvent.java b/src/main/java/me/trouper/armorsmp/server/events/JoinEvent.java index 1978987..5045188 100644 --- a/src/main/java/me/trouper/armorsmp/server/events/JoinEvent.java +++ b/src/main/java/me/trouper/armorsmp/server/events/JoinEvent.java @@ -31,7 +31,7 @@ public class JoinEvent implements CustomListener { final Map armorCache = ArmorSMP.getInstance().getManager().io.storage.armorUpdateCache; if (armorCache.containsKey(p.getUniqueId().toString()) || !ArmorSMP.getInstance().getManager().armor.verifyArmor(p)) { Verbose.send("Updating armor"); - ArmorSMP.getInstance().getManager().armor.queueUpdate(p,armorCache.get(p.getUniqueId().toString())); + ArmorSMP.getInstance().getManager().armor.queueUpdate(p,armorCache.getOrDefault(p.getUniqueId().toString(),true)); ArmorSMP.getInstance().getManager().io.storage.armorUpdateCache.remove(p.getUniqueId().toString()); } final Set uniquesCache = ArmorSMP.getInstance().getManager().io.storage.uniqueUpdateCache; diff --git a/src/main/java/me/trouper/armorsmp/server/events/TrustEvents.java b/src/main/java/me/trouper/armorsmp/server/events/TrustEvents.java new file mode 100644 index 0000000..3d25561 --- /dev/null +++ b/src/main/java/me/trouper/armorsmp/server/events/TrustEvents.java @@ -0,0 +1,30 @@ +package me.trouper.armorsmp.server.events; + +import io.github.itzispyder.pdk.events.CustomListener; +import me.trouper.armorsmp.ArmorSMP; +import org.bukkit.entity.AreaEffectCloud; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; + +import java.util.Set; + +public class TrustEvents implements CustomListener { + @EventHandler + public void onDamage(EntityDamageByEntityEvent e) { + if (!(e.getEntity() instanceof Player v)) return; + Set trustees = ArmorSMP.getInstance().getManager().trust.getTrustees(v); + String damager = e.getDamager().getUniqueId().toString(); + + if (trustees.contains(damager)) { + e.setCancelled(true); + return; + } + if (e.getDamager() instanceof AreaEffectCloud aoe && aoe.getOwnerUniqueId() != null) { + if (trustees.contains(aoe.getOwnerUniqueId().toString())) { + e.setCancelled(true); + return; + } + } + } +} diff --git a/src/main/java/me/trouper/armorsmp/server/systems/ArmorBackend.java b/src/main/java/me/trouper/armorsmp/server/systems/ArmorBackend.java index e4dfa15..aa87b16 100644 --- a/src/main/java/me/trouper/armorsmp/server/systems/ArmorBackend.java +++ b/src/main/java/me/trouper/armorsmp/server/systems/ArmorBackend.java @@ -51,7 +51,7 @@ public class ArmorBackend { } public boolean upTier(OfflinePlayer target) { - int numeric = storage.userData.playerTiers.get(target.getUniqueId().toString()).getNumeric(); + int numeric = storage.userData.playerTiers.computeIfAbsent(target.getUniqueId().toString(),tier->ArmorTier.NONE).getNumeric(); Verbose.send("Upgrading %s, current numeric: %s",target.getName(),numeric); if (numeric > 4) return false; numeric++; diff --git a/src/main/java/me/trouper/armorsmp/server/systems/Broadcaster.java b/src/main/java/me/trouper/armorsmp/server/systems/Broadcaster.java index c531159..1f0d365 100644 --- a/src/main/java/me/trouper/armorsmp/server/systems/Broadcaster.java +++ b/src/main/java/me/trouper/armorsmp/server/systems/Broadcaster.java @@ -4,6 +4,7 @@ import io.github.itzispyder.pdk.utils.misc.Randomizer; import me.trouper.armorsmp.ArmorSMP; import me.trouper.armorsmp.data.io.IO; import me.trouper.armorsmp.utils.Text; +import org.bukkit.entity.Player; public class Broadcaster { @@ -15,6 +16,9 @@ public class Broadcaster { public void broadcastTip() { String tip = new Randomizer().getRandomElement(io.config.tips.tipList); - ArmorSMP.getInstance().getServer().broadcast(Text.getMessage(false, Text.Pallet.NEUTRAL,tip)); + for (Player onlinePlayer : ArmorSMP.getInstance().getServer().getOnlinePlayers()) { + if (ArmorSMP.getInstance().getManager().io.storage.userData.tipsDisabled.contains(onlinePlayer.getUniqueId().toString())) continue; + onlinePlayer.sendMessage(Text.getMessage(false, Text.Pallet.NEUTRAL,tip)); + } } } diff --git a/src/main/java/me/trouper/armorsmp/server/systems/UniquesBackend.java b/src/main/java/me/trouper/armorsmp/server/systems/UniquesBackend.java index f2fc4c1..80da80d 100644 --- a/src/main/java/me/trouper/armorsmp/server/systems/UniquesBackend.java +++ b/src/main/java/me/trouper/armorsmp/server/systems/UniquesBackend.java @@ -1,5 +1,6 @@ package me.trouper.armorsmp.server.systems; +import me.trouper.armorsmp.ArmorSMP; import me.trouper.armorsmp.data.io.IO; import me.trouper.armorsmp.data.io.Storage; import me.trouper.armorsmp.data.Unique; @@ -7,6 +8,8 @@ import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; import org.bukkit.entity.Player; +import java.util.UUID; + public class UniquesBackend { private final Storage storage; @@ -15,20 +18,22 @@ public class UniquesBackend { storage = io.storage; } - private void updateUniques(Player p) { - if (!storage.uniques.owners.containsValue(p.getUniqueId().toString())) return; - for (Player player : Bukkit.getOnlinePlayers()) { - - } - storage.uniques.owners.forEach((unique,owner)->{ - if (unique.equals(Unique.MACE) || unique.equals(Unique.SWORD) || unique.equals(Unique.AXE) && owner.equals(p.getUniqueId().toString()) && !p.getInventory().contains(unique.getInGameItem())) { - p.getInventory().addItem(unique.getInGameItem()); + private void updateUniques() { + ArmorSMP.getInstance().getServer().getOnlinePlayers().forEach(this::updateUniques); + } + + public void updateUniques(Player p) { + ArmorSMP.getInstance().getManager().io.storage.uniques.owners.forEach(((unique, id) -> { + if (id.equals(p.getUniqueId().toString())) { + if (!p.getInventory().contains(unique.getInGameItem())) p.getInventory().addItem(unique.getInGameItem()); + } else { + p.getInventory().removeItemAnySlot(unique.getInGameItem()); } - }); + })); } public void queueUpdate(OfflinePlayer target) { - if (target.getPlayer() != null && target.isOnline()) updateUniques(target.getPlayer()); + if (target.getPlayer() != null && target.isOnline()) updateUniques(); else storage.uniqueUpdateCache.add(target.getUniqueId().toString()); } diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 4625655..cf54608 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -18,4 +18,8 @@ commands: usage: "/asmp usage" aliases: - asmp - - armor_smp \ No newline at end of file + - armor_smp + ability: + description: Utilize unique abilities. + aliases: + - a \ No newline at end of file